Reputation: 1169
I have been working over the last few days to add an animated header to my screens. I have succeeded in this however I would now like to apply this as my header by default rather then copying and pasting the code into all screens I wish to use it. At the moment the animated header is implemented in the screen as follows:
To render the header:
static navigationOptions = ({ navigation }) => {
return {
header: () => {
return (
<SafeAreaView style={{
height: 0,
overflow: 'visible',
}}>
<Animated.View style={{height: 80, width: 80,
transform: [ {translateY: navigation.getParam('headerScrollY', 0)}]
}}>
<TouchableOpacity style={{padding: 20}} onPress={() => navigation.goBack()}>
<Icon.Ionicons style={{color: '#ffffff', width: 50, height: 50}} name={'ios-arrow-round-back'} size={50} />
</TouchableOpacity>
</Animated.View>
</SafeAreaView>
)
}
}
};
To setup the state:
constructor() {
super();
this.state = {
headerScrollY: new Animated.Value(0),
};
}
To set the animation interpolation and pass value to navigation props (this is what I am going to have to access later when rendering the header)
componentWillMount() {
this.props.navigation.setParams({
headerScrollY: this.state.headerScrollY.interpolate({
inputRange: [0, 80],
outputRange: [0, -80],
})
});
}
Main render method with "scrollView" calling "onScroll" event to pick up scrolling action
render() {
return (
<ScrollView
style={Styles.wholePageContainer}
showsVerticalScrollIndicator={false}
scrollEventThrottle={16}
onScroll={Animated.event( [{nativeEvent:{contentOffset: {y: this.state.headerScrollY}}}])}
>
...
</ScrollView>
);
}
To set the default header I must set the "header" value of "defaultNavigationOptions" when I use "createStackNavigator". I am able to use this to create a simple defaultHeader in red with height of 100 (code and image below):
const HomeStack = createStackNavigator({
Home: HomeScreen,
Category: CategoryScreen,
Venue: VenueScreen,
Activity: ActivityScreen,
}, {
headerMode: 'screen',
defaultNavigationOptions: {
header: <View style={{backgroundColor: '#ff0000', height: 100}} />
,
},
});
Simulator demonstrating application of simple default header
Unfortunately for my animated header I require the "navigation" prop as this is used to store the animation values. I have tried many approaches into passing this to where I need the values and was wondering if anyone knew how to do this or if it is even possible or if anyone had any suggestions.
Upvotes: 4
Views: 2207
Reputation: 1169
Thanks to Hend El-Sahli I have now got the code to work as intended. The result (for future reference for others) is as before however removing the header definitions in the navigation options for each screen and the "createStackNavigator" call is as follows:
const HomeStack = createStackNavigator({
Home: HomeScreen,
Category: CategoryScreen,
Venue: VenueScreen,
Activity: ActivityScreen,
}, {
headerMode: 'screen',
defaultNavigationOptions: ({ navigation }) => ({
header:
<SafeAreaView style={{
height: 0,
overflow: 'visible',
}}>
<Animated.View style={{height: 80, width: 80,
transform: [ {translateY: navigation.getParam('headerScrollY', 0)}]
}}>
<TouchableOpacity style={{padding: 20}} onPress={() => navigation.goBack()}>
<Icon.Ionicons style={{color: '#ffffff', width: 50, height: 50}} name={'ios-arrow-round-back'} size={50} />
</TouchableOpacity>
</Animated.View>
</SafeAreaView>
}),
});
Upvotes: 6