It's possible to animate the Native Stack header, but since only Animated components accept animated styles in Reanimated 2, you'd probably have to create a new component for the header (an Animated.Something)...
We can achieve this by using the header option, which can be found here.
A simple example built with Expo:
import React from "react";
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
import { NavigationContainer, useNavigation } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import Animated, {
useSharedValue,
useAnimatedStyle,
useAnimatedScrollHandler,
interpolateColor,
} from "react-native-reanimated";
const Stack = createNativeStackNavigator();
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
},
item: {
padding: 20,
margin: 15,
backgroundColor: "whitesmoke",
},
header: {
paddingTop: 50,
padding: 15,
borderColor: "whitesmoke",
borderBottomWidth: 1,
},
headerTitle: {
fontSize: 20,
fontWeight: "bold",
},
});
function WelcomeScreen() {
const navigation = useNavigation();
const translationY = useSharedValue(0);
const scrollHandler = useAnimatedScrollHandler((event) => {
translationY.value = event.contentOffset.y;
});
const aStyle = useAnimatedStyle(() => ({
backgroundColor: interpolateColor(
translationY.value,
[0, 50],
["white", "skyblue"],
"RGB"
),
}));
React.useLayoutEffect(() => {
navigation.setOptions({
header: () => (
<Animated.View style={[styles.header, aStyle]}>
<Text style={styles.headerTitle}>Testing</Text>
</Animated.View>
),
});
}, [aStyle, navigation]);
return (
<View style={styles.container}>
<Animated.ScrollView onScroll={scrollHandler} scrollEventThrottle={16}>
{Array(15)
.fill(0)
.map((_, index) => (
<View style={styles.item} key={`${index}`}>
<Text>Item {`${index}`}</Text>
</View>
))}
</Animated.ScrollView>
<StatusBar style="auto" />
</View>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen component={WelcomeScreen} name="Welcome" />
</Stack.Navigator>
</NavigationContainer>
);
}
Note that in this example, we're passing an Animated.View to the header option, passing our animated style (aStyle) to it as a style.
Also, just like you did, I'm using useAnimatedScrollHandler to track the scroll position, and interpolating (with interpolateColor) the backgroundColor of the header accordingly (between 'white' and 'skyblue', so it's easier to visualize).
Uploaded this example to this Snack so you can easily test it if you want.
I Hope this helps you solve your problem!