I am creating an application in React Native, I am using React Navigation 5.x and I have replaced the default header with one created by me, this is part of code:
App.js
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home" drawerContent={SideMenu} drawerStyle={{
backgroundColor: '#fff',
width: Dimensions.get('window').width - 120,
}}>
<Drawer.Screen name="Home" component={StackNav} />
</Drawer.Navigator>
</NavigationContainer>
StackNav.js
<Stack.Navigator headerMode="float" screenOptions={{
cardShadowEnabled: false,
cardOverlayEnabled:false,
headerTransparent: true,
headerBackTitleVisible: false,
gestureEnabled: true,
headerTintColor: currentTheme.colors.primary,
headerTitleStyle: styles.headerTitle,
gestureDirection:"horizontal",
headerStyleInterpolator: HeaderStyleInterpolators.forStatic,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
header: ({ scene, previous, navigation }) => {
const { options } = scene.descriptor;
const title =
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
? options.title
: scene.route.name;
return (
<MyHeader click={() => addCart()} ref={myRef} scene={scene} onPress={navigation.goBack} navigation={navigation}/>
);
}
}}>
<Stack.Screen name="Home" component={Home} options={{title: 'Home'}}/>
<Stack.Screen name="Menu" component={RestaurantMenu} options={({ route }) => ({ title: route.params.name })}/>
<Stack.Screen name="Piatti" component={MenuItems} options={({ route }) => ({ title: route.params.name })}/>
<Stack.Screen name="Carrello" component={Cart} options={({ route }) => ({ title: route.params.name })}/>
</Stack.Navigator>
MyHeader.js
import * as React from 'react';
import { StyleSheet, Button, SafeAreaView, TouchableOpacity, Image,View, Text } from 'react-native';
const styles = StyleSheet.create({
containerSafe: {
flex: 1,
flexDirection:"row",
justifyContent: "space-between"
},
containerLeft: {
zIndex: 1,
alignSelf: 'flex-start',
left: 0,
marginTop:25,
marginLeft:10,
width: 25,
height: 25,
justifyContent: 'center',
alignContent: 'center'
},
containerCenter: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
containerRight: {
zIndex: 1,
alignSelf: 'flex-end',
right: 0,
marginTop:25,
marginRight:10,
width: 25,
height: 25,
justifyContent: 'center',
alignContent: 'center'
}
});
class CartButton extends React.Component {
constructor(props) {
super(props);
}
render(){
return (
<TouchableOpacity onPress={() => this.props.onPress()} style={styles.containerRight}>
<Image style={{width:"100%", height:"100%"}}
source={require('../assets/cart.png')}
/>
<Text>{this.props.nCart}</Text>
</TouchableOpacity>
)
}
}
class HomeButton extends React.Component {
constructor(props) {
super(props);
}
render(){
return (
<TouchableOpacity onPress={() => this.props.onPress()} style={styles.containerLeft}>
<Image style={{width:"100%", height:"100%"}}
source={require('../assets/menu.png')}
/>
</TouchableOpacity>
)
}
}
class BackButton extends React.Component {
constructor(props) {
super(props);
}
render(){
return (
<TouchableOpacity onPress={() => this.props.onPress()} style={styles.containerLeft}>
<Image style={{width:"100%", height:"100%"}}
source={require('../assets/leftArrow.png')}
/>
</TouchableOpacity>
)
}
}
class MyHeader extends React.Component {
constructor(props) {
super(props);
this.state= {
nCart: 0
}
this.addCart = this.addCart.bind(this);
}
addCart(){
var current = this.state.nCart;
this.setState({
nCart: current +1
})
}
render(){
return(
<SafeAreaView style={styles.containerSafe}>
{(this.props.scene.route.name === "Home")? <HomeButton onPress={() =>this.props.navigation.openDrawer()} /> : <BackButton onPress={() => this.props.navigation.goBack()} />}
<Button title="click" onPress={(() => this.props.click())} />
<CartButton nCart={this.state.nCart} onPress={() => this.props.navigation.navigate('Carrello', {name: 'Carrello'})} />
</SafeAreaView>
)
}
}
export default MyHeader;
but it gives me this problem
The Back button and the Cart button overlap when I change the screen, but the burger menu should disappear and become the arrow of the back button while the cart should simply update in the counter as it does in the home.
I solved it by adding this piece of code
const progress = Animated.add(scene.progress.current, scene.progress.next || 0);
const opacity = progress.interpolate({
inputRange: [0, 1, 2],
outputRange: [0, 1, 0],
});
return (
<Animated.View style={{ opacity }}><MyHeader click={() => addCart()} ref={myRef} scene={scene} onPress={navigation.goBack} cartElement={cart} navigation={navigation}/></Animated.View>
);
https://reactnavigation.org/docs/en/stack-navigator.html#header
When using a custom header, it's recommended set the
headerMode
prop on the navigator toscreen
so that you don't have to implement animations.If you want your custom header to animate with screen transitions and want to keep
headerMode
asfloat
, you can interpolate on thescene.progress.current
andscene.progress.next
props.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With