How to customize headerLeft React Navigation? - react-native

How can I customize headerLeft TabNavigator of React Navigation.
Here's one of my screens :
I want to remove the Back from the headerLeft
Is it possible ?
Here's my code :
DetailTabs = TabNavigator({
DetailResult:{
screen:DetailResult,
navigationOptions:{
title:'Detail Penginapan',
headerTitleStyle:{
fontSize:14,
textAlign: "center",
flex: 1,
},
tabBarVisible: false,
headerStyle:{
backgroundColor:'#4A94FB',
borderBottomColor: 'transparent',
},
headerTintColor: 'white'
}
}
})

By default, HeaderBackButton component is used. You can implement it and use it to override the back button styles, press props, for example:
link to docs
import { HeaderBackButton } from '#react-navigation/stack';
//in newer versions use:
//import {HeaderBackButton} from '#react-navigation/elements';
const styles = StyleSheet.create({
custom: {
// Custom styles here
}
});
<Screen
name="Home"
component={HomeScreen}
options={{
headerLeft: (props) => (
<HeaderBackButton
{...props}
style={styles.custom}
onPress={() => {
// Do something
}}
/>
),
}}
/>;
If you want full control, you can use your custom back button component, example:
import { CustomBackButton } from 'path/to/custom/component';
<Screen
name="Home"
component={HomeScreen}
options={{
headerLeft: (props) => (
<CustomBackButton {...props} />
),
}}
/>;

You probably just need to set headerBackTitle to null. Check out the docs for headerLeft for more info.
Like this:
DetailTabs = TabNavigator({
DetailResult:{
screen:DetailResult,
navigationOptions:{
title:'Detail Penginapan',
headerTitleStyle:{
fontSize:14,
textAlign: "center",
flex: 1,
},
tabBarVisible: false,
headerStyle:{
backgroundColor:'#4A94FB',
borderBottomColor: 'transparent',
},
headerTintColor: 'white',
headerBackTitle: null,
}
}
})

Key is to put this code from where the back button is clicked, not in App.js
In sample below, for Icon to work, use import Icon from 'react-native-vector-icons/Feather';
constructor(props) {
super(props);
this.state = {
// what ever
};
this.props.navigation.setOptions({
headerLeft: () => (
<TouchableOpacity
onPress={() => this.props.navigation.navigate('Home')}
>
<Icon style = {{paddingLeft : 10}} name="arrow-left" size={26} color="black" />
</TouchableOpacity>
),
});
}

Related

how to get drawerOpen() to stack navigator screen Options

i have this stack navigator:
const StackNavigator = () => (
<Stack.Navigator headerMode="screen" navigationOptions screenOptions={ss}>
<Stack.Screen name="Main" component={MainScreen} headerMode="screen" />...............
and i have object of screen options:
const ss = {
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
gestureEnabled: true,
gestureDirection: "horizontal",
headerTitleAlign: "center",
headerHideShadow: true,
headerTintColor: "red",
headerStyle: {
borderBottomWidth: 0.5,
borderColor: "white",
backgroundColor: "#1d2731",
},
headerTitleStyle: {
color: "white",
},
headerLeft: () => <AnimateHamburger navigation={navigation} />,
};
no when i get inside the component AnimatedHamburger
i dont get the props of openDrawer ...i get "...
navigation.openDrawer is not function....................
the AnimateHamburger component:
const AnimateHamburger = ({ navigation }) => {
console.log(navigation);
const isDrawerOpen = useIsDrawerOpen();
const toggleMenu = () => {
navigation.openDrawer();
};
return (
<View style={styles.icon}>
<Icon
style={styles.icon}
onPress={toggleMenu}
name={isDrawerOpen ? "enter" : "bars"}
type={isDrawerOpen ? "antdesign" : "font-awesome"}
color="black"
size={30}
/>
</View>
);
};
PLEASE help me how can i get the navigation props to toggle my drawer from the AnimateHamburger component
If you receiving openDrawer is not a function that's probably you are trying to access this method in a nested navigator which don't know about the parent drawer navigator. You can access drawer methods with DrawerAction from react-navigation take a look here:
https://reactnavigation.org/docs/drawer-actions
And use it like this:
https://reactnavigation.org/docs/nesting-navigators/#navigator-specific-methods-are-available-in-the-navigators-nested-inside

Set onpress on createDrawerNavigator item in react native?

I have a drawer item "Share App" where I want to open an alert and display a message rather than opening an entire screen in react native. My code is as follows:
const Screen6_StackNavigator = createStackNavigator({
//All the screen from the Screen6 will be indexed here
Sixth: {
screen: ShareApp, //don't want this screen
title:'Share',
navigationOptions: ({ navigation }) => ({
headerLeft: () => <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#138808',
},
headerTintColor: '#fff',
}),
},
});
const DrawerNavigatorExample = createDrawerNavigator({
ShareApp: {
//Title
screen: Screen6_StackNavigator,
navigationOptions: {
drawerLabel: 'Share App',
drawerIcon: (<Entypo name="share" size={20} color='black'></Entypo>)
},
},
);
Where Do I add the onPress parameter in order to call the function? I dont want the screen parameter, want a function to be called only when I click on Share App.
How to do that in react native??
Do help as I am new in React native development....
Thanks.
You can create a custom drawer content component and pass it to the contentComponent option in the DrawerNavigatorConfig.
Creating the custom drawer content:
const CustomDrawerContentComponent = (props) => (
<ScrollView>
<SafeAreaView
style={{ flex: 1 }}
forceInset={{ top: 'always', horizontal: 'never' }}>
<TouchableOpacity
onPress={() => {
// Do something...
Alert.alert('Heading', 'Body');
}}
style={{ left: 15, flexDirection: 'row', alignItems: 'center' }}>
<Entypo name="share" size={20} color='black'></Entypo>
<Text style={{ marginLeft: 30, fontWeight: 'bold' }}>Share App</Text>
</TouchableOpacity>
<DrawerItems {...props} />
</SafeAreaView>
</ScrollView>
);
The DrawerItems component will render clickable drawer options based on the screens you create, but above the DrawerItems we can add your share button for example.
Passing the custom drawer content component to contentComponent
const DrawerNavigatorExample = createDrawerNavigator(
{
Screen1: {
// Properties...
},
// Other screens...
},
{
// Pass custom drawer content component...
contentComponent: props => <CustomDrawerContentComponent {...props} />,
// Other configurations...
},
);
DrawerItems should be imported from react-navigation-drawer.

having problem with react-native navigation | undefined is not an object (evaluating '_this.props.navigation')

hi i'm working on a new react-native app, but i had some issues with the navigation from a component to a screen.
this is the link for the code on snack: https://snack.expo.io/#mimonoux/my-app-navigation-test
i have already tried this
<ButtonCarte onPress={() => this.props.navigation.navigate('Carte') } />.
but it didn't work. please if anyone could help me with this please check the snack link and take a deep look at the easy code i made for my real problem
I saw your problem now. With react-navigation,
navigation props exists in a component when : either the component is configured in your route configuration object that you defined in App.js, either you use the withNavigation HOC ( https://reactnavigation.org/docs/en/with-navigation.html ).
Now in the Medicine_listDetail component this.props.navigation does not exist since Medicine_listDetail does not appear in your route and also the props object should not be read by this.props in a functional component. You can do one of this two way :
const Medicine_listDetail = ({medicine, navigation}) => {
// i'm passing navigation props comme from parent component that have
// navigation object
// ...
}
// OR you can do
const Medicine_listDetail = (props) => {
const { medicine, navigation } = props;
// i'm passing navigation props comme from parent component that have
// navigation object
// ...
}
Hence the following is an attempt at a solution that work for me.
Medicine_listDetail component : i'm passing navigation props come from
parent component that have navigation object
...
const Medicine_listDetail = ({medicine, navigation}) => {
const {title, coordinate} = medicine;
const {
headerContentStyle,
headerTextStyle,
cityTextStyle,
addTextStyle,
infoContainerStyle,
buttonsContainerStyle,
specialityTextStyle,
buttonStyle,
textStyle
} = styles
return (
<View>
<View style={headerContentStyle}>
<Text style={headerTextStyle}>{title}</Text>
</View>
<View style={buttonsContainerStyle}>
<ButtonCarte onPress={() => navigation.navigate('Carte') }>
</ButtonCarte>
</View>
</View>
);
};
...
ButtonCarte component
const ButtonCarte = ({onPress, children}) => {
const {buttonStyle, textStyle} = styles;
return (
<TouchableOpacity onPress={() => onPress()} style={buttonStyle}>
<Ionicons name={'ios-pin'} size={20} color="white" />
<Text style={textStyle}>
Voir La Carte
</Text>
</TouchableOpacity>
);
};
Medicin component : in all_medicine() function, i'm passing navigation object in props of Medicine_listDetail component. So this is the trick.
export default class Medicin extends React.Component {
constructor(props) {
super(props);
this.state = {
list_allMedicine: data_allMedicine,
selectedIndex: 0,
};
this.updateIndex = this.updateIndex.bind(this);
}
updateIndex(selectedIndex) {
this.setState({ selectedIndex });
}
all_medicine() {
const { navigation } = this.props;
return this.state.list_allMedicine.map(medicine => (
<Medicine_listDetail key={medicine.title} medicine={medicine} navigation={navigation} />
));
}
render() {
const buttons = ['Tout', '...', '...', '...'];
const { selectedIndex } = this.state;
return (
<View style={{ flex: 1}}>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ButtonGroup
onPress={this.updateIndex}
selectedIndex={selectedIndex}
buttons={buttons}
containerStyle={{ borderRadius:8 }}
/>
</View>
<Divider
style={{
backgroundColor: 'lightgrey',
marginHorizontal: 5,
height: 2,
}}
/>
<View style={{ flex: 5 }}>
{this.state.selectedIndex == 0 ? (
<ScrollView>{this.all_medicine()}</ScrollView>
) : (
<Text>test</Text>
)}
</View>
</View>
);
}
}
At least in App.js, i change the name of carte tab from Cart to Carte because of your RootStack stack.
export default createAppContainer(
createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: ({ tintColor }) => (
<Ionicons name={'ios-home'} size={25} color={tintColor} />
),
},
},
Medicin: {
screen: Medicin,
navigationOptions: {
tabBarLabel: 'Medicin',
tabBarIcon: ({ tintColor }) => (
<Image
source={require('./assets/images/Dashboard/drawable-xhdpi/doctor_heart.png')}
style={{ width: 25, height: 20, tintColor: tintColor }}
/>
),
},
},
Carte: {
screen: Carte,
navigationOptions: {
tabBarLabel: 'Carte',
tabBarIcon: ({ tintColor }) => (
<Ionicons name={'ios-map'} size={25} color={tintColor} />
),
},
},
},
{
tabBarOptions: {
activeTintColor: 'black',
inactiveTintColor: 'gray',
},
}
)
);
I test this and it work for me.
try adding this:
import { NavigationEvents, NavigationActions } from 'react-navigation';
Here is a screenshot of what's available in props in reference to the comments below:
Here is a screenshot of what I mentioned in the comments. You can see where I added a console.log. It shows in the console that although navigation is in this.props, actions within navigation is empty. I think that is the source of the problem. If you put more console.logs like the one I've done you will see where in the project it loses that information.

navigationOptions headerLeft,headerRight and title not working?

What I want: put a touchable icon left side that will navigate to my drawer navigator once pressed and the title in the middle then in the right side an icon that has future purposes once clicked
What I tried doing:
I tried to put the navigationOptions under the MainScreen it still doesn't work.
This is my code in my AppNavigation.js
const primaryNav = createStackNavigator({
LaunchScreen: { screen: LaunchScreen },
MainScreen: {
screen: MainScreen,
},
}, {
// Default config for all screens
headerMode: 'none',
initialRouteName: 'MainScreen',
navigationOptions: {
headerStyle: styles.header,
title: 'TY, Next',
headerStyle:{
backgroundColor: "Transparent",
marginRight: 20,
marginLeft: 20,
},
headerRight: (
<TouchableOpacity>
<Icon2 name="sc-telegram" color={Colors.red} size={30} />
</TouchableOpacity>
),
headerLeft: (
<TouchableOpacity>
<Icon name="bars" color={Colors.red} size={25}/>
</TouchableOpacity>
),
}
})
Any idea why my code isn't running? There's no title of Ty next not even the 2 icons that I added. I am using igniteCLI for react native.
I made it work by using the following codes in my screen.
static navigationOptions = ({ navigation }) => {
const {state} = navigation;
const {} = state;
return {
headerStyle:{
backgroundColor: "Transparent",
marginRight: 20,
marginLeft: 20,
},
headerLeft: (
<TouchableOpacity>
<Icon name="bars" color={Colors.red} size={25}/>
</TouchableOpacity>
),
headerLeftStyle: styles.drawerIcon,
headerRight: (
<TouchableOpacity>
<Icon2 name="sc-telegram" color={Colors.red} size={30} />
</TouchableOpacity>
),
headerRightStyle: styles.planeIcon,
headerTransparent: true,
};
}
Use Icon instead of Icon2
if you are using version with 3x
defaultNavigationOptions
instead of navigationOptions
headerRight: (
<TouchableOpacity>
//-->I changed here <Icon name="sc-telegram" color={Colors.red} size={30} />
</TouchableOpacity>
),
Because that methods are deprecated in 'navigationOptions'.
headerRight: <SomeElement /> will be removed in a future version.
As like
headerRight: () => <SomeElement />

DrawerNavigator cant set background to transparent whatever I do?

I have spend more than si hours trying to change the background of the DrawerNavigator to transparent without any success.
When I write
when I change it in the main component it works
const MainTabBarDrawer = DrawerNavigator({
Home:{
screen:MainTabNavigator,
},
},{
drawerWidth: 200,
drawerPosition: 'right',
// contentComponent: props => <Text style={{color:'white'}} >text
</Text>,
drawerBackgroundColor: 'yellow',
//backgroundColor:'transparent',
// style: {
// //backgroundColor: 'transparent',
// flex: 1
// },
// contentOptions: {
// style: {
// backgroundColor: 'transparent',
// flex: 1
// }
},
{
style: {
backgroundColor: 'transparent',
flex:1
}
}
)
class App extends Component{
render()
{
return(<MainTabBarDrawer style={{backgroundColor: 'transparent'}}/>)
//return(<Login/>)
}
}
While the above approach will work my layout is much complex and I don't want the drawer to appear in all my views.
So dose any body know If I can change the background of the DrawerNavigator directly without rendering it as a component?
In React Navigation 5, this would be:
<Drawer.Navigator
initialRouteName={...}
drawerContent={...}
drawerStyle={{backgroundColor: 'transparent'}}
>
Add drawerBackgroundColor: "transparent" to drawerConfig.
I think you are looking for drawerContentOptions or drawerStyle of Drawer.Navigator
<NavigationContainer>
<Drawer.Navigator
..........
drawerPosition="left"
drawerContentOptions={{
activeBackgroundColor:"transparent", //here change it
}}
drawerStyle={{backgroundColor: 'transparent'}} //or here
initialRouteName="Splash">
<Drawer.Screen
name="HomePage"
component={StackScreen}
options={{
drawerLabel: () => {return null},
title:null,
drawerIcon: () => {return <AppIconImage/>}
}}
/>
</Drawer.Navigator>
</NavigationContainer>
The issue was fixed since I have updated to the latest version
1.0.0-beta.16
Adding the style backgroundColor: 'transparent' to drawerStyle inside the screenOptions param of Drawer.Navigator worked for me.
import React from 'react';
import {createDrawerNavigator} from '#react-navigation/drawer';
import CustomDrawer from '../components/Drawer';
const Drawer = createDrawerNavigator();
const DrawerNavigator = () => {
return (
<Drawer.Navigator
initialRouteName="Stack"
screenOptions={{
headerShown: false,
drawerStyle: {width: '80%', backgroundColor: 'transparent'}, // Add this.
}}
drawerContent={props => <CustomDrawer {...props} />}>
// Screens that go inside the navigator.
</Drawer.Navigator>
);
};
export default DrawerNavigator;
P.S.: I am using #react-navigation/drawer: ^6.5.0.
For ReactNavigation Version 6.
try
<Drawer.Navigator
initialRouteName={...}
drawerContent={...}
screenOptions={{
drawerStyle: {
backgroundColor: 'transparent',
},
}}>
Adding React Docs link for reference.
https://reactnavigation.org/docs/drawer-navigator#drawerstyle