customized tab navigation with two tabs - react-navigation

using react-navigation I'm trying to build a tab navigation with 3 screens, one screen to be the Main screen which is showing the bottom tabs to other two screen that is Filter and Sort modal screen. right now, I can't do this with createBottomTabNavigator as it switches between screen and that tabs is added in all screens.

You could create a regular stack navigator and in this navigator you should use the other 'main' tab navigator. Something like:
const App = createStackNavigator();
<App.Navigator>
<App.Screen name="TABNAVIGATORS" component={TABNAVIGATORS} />
</App.Navigator>
Then, on the TABNAVIGATORS component you create as you wish:
const Tab = createMaterialBottomTabNavigator();
<Tab.Navigator>
<Tab.Screen
name="Home"
component={MainScreen}
options={{
tabBarLabel: '',
tabBarIcon: () => <Entypo name="home" size={24} color="#FFF" />,}}
/>
...
</Tab.Navigator>

Related

How to get navigation object outside Screen

I have the following code in the App.tsx:
export default function App() {
...
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="StackNavigation"
drawerContent={(props) => <MainPageDrawer {...props} />}
screenOptions={{ swipeEnabled: false }}
>
<Drawer.Screen name="StackNavigation" component={StackNavigator} />
</Drawer.Navigator>
</NavigationContainer>
);
...
}
As you see, the MainPageDrawer component isn't inside the Drawer.Screen component. But I still need to get access to navigation object inside MainPageDrawer. When I do something lake this inside MainPageDrawer:
const navigation = useNavigation<MainScreenNavigationProp>();
I get the following error:
Couldn't find a navigation object. Is your component inside a screen in a navigator?
What is the right way to get access to the navigation object outside Screen component?
Solution: I figured out that useNavigation won't work anyway if it is outside Screen, BUT this:
(props) => <MainPageDrawer {...props} />
still pass navigation through props, so you can easily access it without useNavigation. I simply restructured navigation:
function MainPageDrawer({ navigation }) {
...
}
And it works

React navigation createMaterialTopTabNavigator inside a screen

React navigation createMaterialTopTabNavigator shows a pretty cool setup at the top of their documentation page:
Notice that the top navigator stack seems to be inside a screen. There is a title at the top "Material Top Tabs" and we can go back to "Examples"
Funny enough, this setup is not given in any of the examples.
I would like to have the same setup and be able to navigate to a specific tab from another screen.
Could someone please share an example code for it?
What I currently have is a basic bottom tab navigation with a
<BottomTab.Screen
name="Tabs"
component={TabsNavigator}
/>
and then
function TabsNavigator() {
const MyTabs = createMaterialTopTabNavigator();
return (
<MyTabs.Navigator
<MyTabs.Screen name="Upcoming" component={TabsUpcomingScreen} />
<MyTabs.Screen name="Past" component={TabsPastScreen} />
</MyTabs.Navigator>
);
}
Although this works when doing navigation.navigate('Tabs', { screen: 'Upcoming' });, I am missing the screen containing the tabs... or the "Tabs" screen (as in the example, it is the "Material Top Tabs" screen)
I could do something like this:
function TabsNavigator() {
const TabsStack = createStackNavigator();
return (
<TabsStack.Navigator>
<TabsStack.Screen name="Tabs" component={TabsScreen} options={{ headerTitle: 'Tabs' }} />
</TabsStack.Navigator>
);
}
function TabsScreen() {
const MyTabs = createMaterialTopTabNavigator();
return (
<MyTabs.Navigator
<MyTabs.Screen name="Upcoming" component={TabsUpcomingScreen} />
<MyTabs.Screen name="Past" component={TabsPastScreen} />
</MyTabs.Navigator>
);
}
But then I am unable to navigate to a specific tab with navigation.navigate('Tabs', { screen: 'Upcoming' });
If you want to navigate to some tab inside of createMaterialTopTabNavigator.Instead of navigation.navigate('Tabs', { screen: 'Upcoming' }) use navigation.jumpTo('Tabs', { name: 'Upcoming' });
https://reactnavigation.org/docs/material-top-tab-navigator#jumpto

Reset stack inside a tab on tab double press using React Navigation 5

I am wondering how to reset a stack inside a BottomTabNavigator if the Tab is focused and pressed.
This is the code I have so far:
const Stack = createStackNavigator<MainStackParams>()
const BottomTab = createBottomTabNavigator<TabNavigatorParams>()
const navigationRef = React.useRef()
> Blockquote
<NavigationContainer ref={navigationRef}>
<Stack.Navigator mode="modal">
<Stack.Screen
name={MainAppRoute.BOTTOM_TAB_NAVIGATOR}
component={BottomTabNavigator}
/>
...
</Stack.Navigator>
</NavigationContainer>
function BottomTabNavigator() {
return (
<BottomTab.Navigator>
<BottomTab.Screen
name={TabNavigatorRoute.SOME_STACK}
component={SomeStack}
listeners={{tabPress: e => {
// TODO: Reset stack in current tab (unsure how to do this)
}}}
/>
...
</BottomTab.Navigator>
)
}
In the TODO (in the code snippet) the following should probably be done:
Get navigationRef from app NavigationContainer
Check if the selected BottomTab is focused (to determine a double press)
e.preventDefault
reset SomeStack (unsure how to get the navigation object a stack inside a BottomTabNavigator)
Have any one been able to do this yet?
Appreciate all answers :)
Okey, basically you have 2 options to manage this, first is to check navigation state, but as i found out, it works only on IOS device, android does not do anything.
This piece of code navigated to first screen from this stacknavigator
<Tab.Screen name={`DeviceNavigatorTab`} component={DeviceNavigator} options={{
tabBarIcon: ({tintColor}) => <Image source={require('../../images/feather_home-menu.png')} style={{width: 26, height: 26, tintColor}}/>,
}} listeners={({ navigation, route }) => ({
tabPress: e => {
if (route.state && route.state.routeNames.length > 0) {
navigation.navigate('Device')
}
},
})} />
The other solution, and even better, works on android and IOS operating systems
DeviceNavigatorTab this is tab navigator screen name, {screen: 'Device'} is the first stack screen name in sub stack navigator, hope it helps
<Tab.Screen name={`DeviceNavigatorTab`} component={DeviceNavigator} options={{
tabBarIcon: ({tintColor}) => <Image source={require('../../images/feather_home-menu.png')} style={{width: 26, height: 26, tintColor}}/>,
}} listeners={({ navigation }) => ({
tabPress: e => {
navigation.navigate('DeviceNavigatorTab', { screen: 'Device' });
},
})} />
It is not actually resetting the navigators, it just goes to specified screen inside that tab navigator.

How to load another screen on top of Home screen when we click on icon in header in Drawer navigation in React-Native

I have created a Drawer Navigation with Home and Cart menu
when i click on Cart symbol on header i want to open separate page on top of this home screen.
I have written code like below
const DrawerNavigationCon=createDrawerNavigator({
Home:HomeNavigation,
Cart:CartNavigation
},{
overlayColor:'gray',
initialRouteName:'Home'
})
and i have written code to navigate from home to cart is like below
const CartNavigation = createStackNavigator({
Cart:CartPage,
},
{
defaultNavigationOptions:({navigation})=>{
return{
headerStyle:{
backgroundColor:'rgb(28, 34, 36)'
},
headerTitle:'Cart',
headerTintColor:'#fff',
headerTitleStyle:{
fontWeight:'bold',
textAlign:'center',
flex:1
},
headerLeft:(
<View>
<Icons name="md-menu" style={{fontSize:35,color:'white',paddingLeft:10}} onPress={()=>navigation.openDrawer()} />
</View>
),
headerRight:(
<View>
<Icons name="md-cart" style={{fontSize:30,color:'white',paddingRight:10}} onPress={() => navigation.navigate('Cart')} />
</View>
)
}
}
})
you can see onPress={() => navigation.navigate('Cart')} in <Icons> Tag
when i click on Cart it's opening like below
But i want to load another page on top of Home page when i click cart like below
how to do like this, please help
Thanks in advance
const DrawerNavigationCon= createStackNavigator({
Home:createDrawerNavigator({
Home:HomeNavigation,
},{
overlayColor:'gray',
initialRouteName:'Home'
}),
Cart:{
screen : CartPage
}
})
Use your stack configuration as shown and configure your stack as per requirement
You can get an idea from the above code.
Basically idea is to use stackNavigator as parent stack and put drawer navigator as child of that stackNavigator and put another route as parallel of that drawer navigator so you can now able to open another screen at top of drawer navigator.

back button with react-navigation on specific screen dynamically

on react-navigation i am trying to navigate to a specific screen which depends on some condition!
Below it is pointing to 'App' page right now
but sometimes i need it to go to 'Main' page
static navigationOptions = ({ navigation }) => {
return {
title: 'Tools',
headerLeft: (
<Button
onPress={() => navigation.navigate('App')}
title="Back"
/>
),
};
};
when i use state or function
for example
...
...
onPress={() => navigation.navigate(this.someFunction())}
...
...
there is an error undefined is not an object
so how do I point dynamically the desirable page to navigate to?
if came from any screen , want to go back dynamic without defining the screen name in navigation . Use this method :
onPress={()=>navigation.goBack()}
navigation.goBack() method will take you directly on the screen where it came from .

Resources