UmnountOnBlur in createMaterialTopTabNavigator - react-native

How to unmount my screen when i change my tab. I am using createMaterialTopTabNavigator() from #react-navigation/material-top-tabs package.
i have tried to add unmonuntOnBlur in options but it doesnt work.
<Tab.Screen name="addIdentity" component={addIdentityStack} options={{ title: 'Add Identity', unmountOnBlur: true }} />
<Tab.Screen name="addVehicle" component={addVehicle} options={{ title: 'Add Vehicle', unmountOnBlur: true }} />

The option 'unMountOnBlur' is not supported in material top navigator
you can check the supported options here
https://reactnavigation.org/docs/material-top-tab-navigator/#options
Only drawer navigator and bottom tab navigator has this option

Related

Share Screens between Tab Navigator and Drawer Navigator while preserving state

My app has 3 main screens (each of which is a Stack Navigator):
MessagesStack
ExpensesStack
CalendarStack
It also has 2 supplemental screens (again, both stacks):
DashboardStack
DocumentsStack
I want to combine a drawer navigator and a tab navigator, but with some overlap. In particular, what I'm trying to achieve is for the drawer navigator to include links to all of the stacks, while the bottom tab navigator contains links only to the three main stacks. The tab navigator should always be visible, on every screen - essentially a sticky footer that enables the user to quickly jump to any of the three main screens. So the layout is like this:
--- Messages
--- Expenses
--- Calendar
--- Dashboard
--- Documents
| Messages | Expenses | Calendar |
Pressing the Messages item in the drawer nav should take the user to the same view as pressing the Messages item from the tab nav. It's important that the state of that view be preserved. In particular, suppose the user opened a specific message in the messages view. This takes them to a MessageDetail screen inside the Messages stack. If they navigate away from the Messages stack and then navigate back, they should still see the MessageDetail screen no matter what navigation route they took.
I've tried a few approaches, but none of them quite work. The closest I got was something like this:
function BottomTabNavigator({ initialRouteName }) {
return (
<BottomTab.Navigator initialRouteName={props.initialRouteName}>
<BottomTab.Screen name="MessagesTab" component={MessagesStackNavigator} />
<BottomTab.Screen name="ExpensesTab" component={ExpensesStackNavigator} />
<BottomTab.Screen name="CalendarTab" component={CalendarStackNavigator} />
<BottomTab.Screen
name="DashboardTab"
component={DashboardStackNavigator}
options={{
tabBarShowLabel: false,
headerShown: false,
tabBarButton: () => <></>,
}}
/>
<BottomTab.Screen
name="DocumentsTab"
component={DocumentsStackNavigator}
options={{
tabBarShowLabel: false,
headerShown: false,
tabBarButton: () => <></>,
}}
/>
</BottomTab.Navigator>
);
}
Then my root navigator was like this:
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen
name="MessagesDrawer"
options={{ title: "Messages" }}
children={() => <BottomTabNavigator initialRouteName="MessagesTab" />}
/>
<Drawer.Screen
name="ExpensesDrawer"
options={{ title: "Expenses" }}
children={() => <BottomTabNavigator initialRouteName="ExpensesTab" />}
/>
<Drawer.Screen
name="CalendarDrawer"
options={{ title: "Calendar" }}
children={() => <BottomTabNavigator initialRouteName="CalendarTab" />}
/>
<Drawer.Screen
name="DashboardDrawer"
options={{ title: "Dashboard" }}
children={() => <BottomTabNavigator initialRouteName="DashboardTab" />}
/>
<Drawer.Screen
name="DocumentsDrawer"
options={{ title: "Documents" }}
children={() => <BottomTabNavigator initialRouteName="DocumentsTab" />}
/>
</Drawer.Navigator>
</NavigationContainer>
Unfortunately, this creates 5 independent TabNavigators which don't share state. So if e.g. the user navigates to Drawer(Messages) -> Tab(Calendar), then navigates away, the next time they tap on Drawer(Messages) it will take them to the Calendar tab! If I set unmountOnRender={true} it solves that problem: tapping Drawer(Messages) will now always open the Messages tab. But the stack state is now lost, so when e.g. the user opens a message, navigates away, and comes back, the message is no longer open.
If it's possible to achieve what I'm trying to do here declaratively that would be ideal, but even if the only way is imperative (e.g. with some navigation.jumpTo calls inside effects in each screen component) that would still be ok. I've tried some imperative approaches but nothing that works yet. Any help is greatly appreciated.

React-Native Tab Navigation drawer navigation how to hide tabbar and header for every screen v6

Trying to hide header and tabbar in Tab navigation in v6
<Tab.Screen
name="LoginScreens"
component={LoginStackScreen}
options={{tabBarVisible: false}}
/>
But here tabBarVisible is not working
After researching found the solution which is different from v5
<Tab.Navigator
screenOptions={{
headerShown: false,
}}>
<Tab.Screen
name="LoginScreens"
component={LoginStackScreen}
options={{
tabBarStyle: {display: 'none'},
}}
/>
</Tab.Navigator>
tabBarStyle: {display: 'none'} to hide the tabbar and headerShown: false is to hide the header for all pages

How can I hide the screen header but show my back button?

I would like to hide my screen header but still show the back button in my Stack Navigator? I have set screenOptions={{ headerShown: false }} in my Stack.Navigator, which hides both the screen header and back button. I would like to just hide the screen header.
Can someone please assist with this? Below is my Stack Navigator:
function SearchStack() {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="SearchScreen" component={SearchScreen} />
<Stack.Screen name="SearchListScreen" component={SearchListScreen} />
</Stack.Navigator>
);
}
In the tab navigator the stack is set as:
<Tab.Navigator screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {...})}>
<Tab.Screen name="Search" component={SearchStack} />
</Tab.Navigator>
This is what I'm currently seeing:
But this is what I would like to have with my Tab navigation bar still at the bottom for the search stack:
This is what I get using options={{headerMode:"none"}} in Stack.Navigator:
The below occurs when adding updating the Stack.Navigator to <Stack.Navigator screenOptions={{ headerTitle:"", headerTransparent:true }}> . How can add or move the back button to the top exactly like the 2nd image, which is achieved when not adding the Stack to the Tab.Screen so changing:
<Tab.Screen name="Search" component={SearchStack} />
to
<Tab.Screen name="Search" component={SearchScreen} />
but doing this causes the tab to not appear in the Search list screen.
The back button is part of the header, so you can't hide the header and keep the back button.
What you want to do is to hide other parts of the header except for the back button, which would be
Title, with headerTitle: ""
Background, with headerTransparent: true
for hide the back button in react-native, we can use property,
headerBackVisible:false this property only work on android
<Stack.Screen
options={{headerBackVisible: false}}
/>
example use of in Stack
const CustomerStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="First"
component={First}
options={{headerShown: false}}
/>
<Stack.Screen
name="Third"
component={Third}
options={{headerTitle: '', headerTransparent: true}}
/>
</Stack.Navigator>
);
}
If you don't want the default header then use like this
screenOptions={{ headerShown: false }}
and write custom code for the header with back button in your component
(If your are using class component) Then
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> </TouchableOpacity>
if you want header title too then,
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> <Text>SearchListScren</Text> </TouchableOpacity>
Put this code at top of the component code under a container

Is there a way to hide one item in a BottomTabNavigator?

I am building a project in react native. I want to use a bottom tab navigator, but the problem i have is that it automatically shows all screens in the navigator.
I want to hide one of the screens from the bar on the bottom.
Try this on your screen that needs to be hidden
const Tab = createBottomTabNavigator();
<Tab.Navigator>
...
<Tab.Screen
name="screen2"
component={screen2}
options={{ tabBarButton: () => null }}
/>
...
</Tab.Navigator>

React navigation 5.x / React native – bottom-tabs navigation with same instance of component

I want to reuse the same instance of one component in two tabs (bottom bar tabs).
created with const Tab = createBottomTabNavigator();
Tab stack:
<Tab.Navigator
tabBarOptions={{
activeTintColor: Colors.tabs.active,
inactiveTintColor: Colors.tabs.inactive,
}}>
<Tab.Screen
name="NavigationMap"
component={Map}
options={{
tabBarLabel: 'Navigation',
}}
/>
<Tab.Screen
name="DiscoveryMap"
component={Map}
options={{
tabBarLabel: 'Discover',
}}
/>
<Tab.Screen
name="Other"
component={OtherComponent}
options={{
tabBarLabel: 'Other',
}}
/>
</Tab.Navigator>
I want to have the same behavior than in the Google Maps application on Android with the "Explore" and "Commute" tabs: stay in the same screen with a different state. I do not want to reload completely my map between the 2 tabs (and have independant zoom levels, center, ...).
Note: I cannot achieve that behavior with the tabPress method.
You can add focus listeners to both screens. Here, you can set the context or global state that can be accessed by the HomeNavigation component and change the behaviour.
<Tab.Screen
name="Home"
component={HomeNavigation}
listeners={{
focus: () => console.warn('focused 1'),
}}
/>
<Tab.Screen
name="Home2"
initialParams={{testing: true}}
component={HomeNavigation}
listeners={{
focus: () => console.warn('focused 2'),
}}
/>