admin管理员组文章数量:1404766
I have a following Expo Router folder structure
- /(tabs)
- _layout.tsx
- home
- messages.tsx
- qr.tsx
- transactions.tsx
- /profile
- _layout.tsx
- account.tsx
- security.tsx
In general, the navigation works fine, when navigating forward but can cause unwanted issues when navigating backwards.
If a user is currently for example on "Profile > Account" screen, he can navigate to "Profile" screen by tapping on Back button. But if the user instead of tapping on back button taps on Profile tab in the Tab toolbar again, then there is a strange behavior of the Navigation. It shortly switches to actual "Profile" screen but still shows the "Account" screen. If the Profile tab is tapped again, then the "Profile" screen is displayed, but from this point on the user can "navigate back" to the "Account" screen. The reason behind all this is I guess because the navigation still goes forward when going to the "Profile" screen.
The desired behavior is that if a user taps on Profile tab in tab toolbar when he is currently in a sub-screen like "Account" it should be the same behavior as pressing on back button. I don't know how to prevent the default behavior and manipulate the navigation in such a way. The closest example of such behavior would be the Facebook iOS app. There exactly this is achieved.
/(tabs)/_layout.tsx
export default function TabsLayout() {
const { bottom } = useSafeAreaInsets()
return (
<Tabs
initialRouteName="home"
screenOptions={{
tabBarHideOnKeyboard: true,
tabBarStyle: [$tabBar, { height: 40 }],
tabBarActiveTintColor: colors.text,
tabBarInactiveTintColor: colors.text,
tabBarLabelStyle: $tabBarLabel,
}}
>
<Tabs.Screen
name="home"
options={{
href: "/home",
headerShown: false,
tabBarAccessibilityLabel: translate("tabsNavigator:homeTab"),
tabBarLabel: translate("tabsNavigator:homeTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="home"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="messages"
options={{
href: "/messages",
headerShown: false,
tabBarAccessibilityLabel: translate("tabsNavigator:messagesTab"),
tabBarLabel: translate("tabsNavigator:messagesTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="message-bulleted"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="qr"
options={{
href: "/qr",
headerShown: false,
tabBarAccessibilityLabel: translate("tabsNavigator:QRTab"),
tabBarLabel: translate("tabsNavigator:QRTab"),
tabBarIcon: ({ focused }) => (
<View style={$tabBarIconQRCode}>
<MaterialCommunityIcons
name="qrcode-scan"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
</View>
),
tabBarIconStyle: {
transform: `translateY(${-tabBarIconSize / 2}px)`,
},
}}
/>
<Tabs.Screen
name="transactions"
options={{
href: "/transactions",
headerShown: true,
headerTitle: "Transactions history",
headerShadowVisible: true,
tabBarAccessibilityLabel: translate("tabsNavigator:transactionsTab"),
tabBarLabel: translate("tabsNavigator:transactionsTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="transfer"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="profile"
options={{
href: "/profile",
headerShown: false,
headerTitle: "Profile",
tabBarAccessibilityLabel: translate("tabsNavigator:profileTab"),
tabBarLabel: translate("tabsNavigator:profileTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="account-circle"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
</Tabs>
)
}
/(tabs)/profile/_layout.tsx
export default function ProfileLayout() {
return (
<Stack
screenOptions={{
headerShown: true,
}}
/>
)
}
Any thoughts on how this could be achieved?
I have a following Expo Router folder structure
- /(tabs)
- _layout.tsx
- home
- messages.tsx
- qr.tsx
- transactions.tsx
- /profile
- _layout.tsx
- account.tsx
- security.tsx
In general, the navigation works fine, when navigating forward but can cause unwanted issues when navigating backwards.
If a user is currently for example on "Profile > Account" screen, he can navigate to "Profile" screen by tapping on Back button. But if the user instead of tapping on back button taps on Profile tab in the Tab toolbar again, then there is a strange behavior of the Navigation. It shortly switches to actual "Profile" screen but still shows the "Account" screen. If the Profile tab is tapped again, then the "Profile" screen is displayed, but from this point on the user can "navigate back" to the "Account" screen. The reason behind all this is I guess because the navigation still goes forward when going to the "Profile" screen.
The desired behavior is that if a user taps on Profile tab in tab toolbar when he is currently in a sub-screen like "Account" it should be the same behavior as pressing on back button. I don't know how to prevent the default behavior and manipulate the navigation in such a way. The closest example of such behavior would be the Facebook iOS app. There exactly this is achieved.
/(tabs)/_layout.tsx
export default function TabsLayout() {
const { bottom } = useSafeAreaInsets()
return (
<Tabs
initialRouteName="home"
screenOptions={{
tabBarHideOnKeyboard: true,
tabBarStyle: [$tabBar, { height: 40 }],
tabBarActiveTintColor: colors.text,
tabBarInactiveTintColor: colors.text,
tabBarLabelStyle: $tabBarLabel,
}}
>
<Tabs.Screen
name="home"
options={{
href: "/home",
headerShown: false,
tabBarAccessibilityLabel: translate("tabsNavigator:homeTab"),
tabBarLabel: translate("tabsNavigator:homeTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="home"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="messages"
options={{
href: "/messages",
headerShown: false,
tabBarAccessibilityLabel: translate("tabsNavigator:messagesTab"),
tabBarLabel: translate("tabsNavigator:messagesTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="message-bulleted"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="qr"
options={{
href: "/qr",
headerShown: false,
tabBarAccessibilityLabel: translate("tabsNavigator:QRTab"),
tabBarLabel: translate("tabsNavigator:QRTab"),
tabBarIcon: ({ focused }) => (
<View style={$tabBarIconQRCode}>
<MaterialCommunityIcons
name="qrcode-scan"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
</View>
),
tabBarIconStyle: {
transform: `translateY(${-tabBarIconSize / 2}px)`,
},
}}
/>
<Tabs.Screen
name="transactions"
options={{
href: "/transactions",
headerShown: true,
headerTitle: "Transactions history",
headerShadowVisible: true,
tabBarAccessibilityLabel: translate("tabsNavigator:transactionsTab"),
tabBarLabel: translate("tabsNavigator:transactionsTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="transfer"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="profile"
options={{
href: "/profile",
headerShown: false,
headerTitle: "Profile",
tabBarAccessibilityLabel: translate("tabsNavigator:profileTab"),
tabBarLabel: translate("tabsNavigator:profileTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="account-circle"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
</Tabs>
)
}
/(tabs)/profile/_layout.tsx
export default function ProfileLayout() {
return (
<Stack
screenOptions={{
headerShown: true,
}}
/>
)
}
Any thoughts on how this could be achieved?
Share Improve this question edited Mar 10 at 15:28 f.bele asked Mar 10 at 13:51 f.belef.bele 3974 silver badges17 bronze badges1 Answer
Reset to default 0If anybody is ever interested in such a solution, I've got it to work. The solution is that you have to define the <Tabs.Screen />
in the _layout
of the path itself. Apart from that you need to turn of the lazy
option because otherwise it doesn't generate the tab properly.
export default function TabsLayout() {
const { bottom } = useSafeAreaInsets()
return (
<Tabs
initialRouteName="home"
screenOptions={{
lazy: false,
tabBarHideOnKeyboard: true,
tabBarStyle: [$tabBar, { height: 40 }],
tabBarActiveTintColor: colors.text,
tabBarInactiveTintColor: colors.text,
tabBarLabelStyle: $tabBarLabel,
}}
>
<Tabs.Screen
name="home"
options={{
href: "/home",
headerShown: false,
lazy: true,
tabBarAccessibilityLabel: translate("tabsNavigator:homeTab"),
tabBarLabel: translate("tabsNavigator:homeTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="home"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="messages"
options={{
href: "/messages",
headerShown: false,
lazy: true,
tabBarAccessibilityLabel: translate("tabsNavigator:messagesTab"),
tabBarLabel: translate("tabsNavigator:messagesTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="message-bulleted"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Tabs.Screen
name="qr"
options={{
href: "/qr",
headerShown: false,
lazy: true,
tabBarAccessibilityLabel: translate("tabsNavigator:QRTab"),
tabBarLabel: translate("tabsNavigator:QRTab"),
tabBarIcon: ({ focused }) => (
<View style={$tabBarIconQRCode}>
<MaterialCommunityIcons
name="qrcode-scan"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
</View>
),
tabBarIconStyle: {
transform: `translateY(${-tabBarIconSize / 2}px)`,
},
}}
/>
<Tabs.Screen
name="transactions"
options={{
href: "/transactions",
headerShown: true,
headerTitle: "Transactions history",
headerShadowVisible: true,
lazy: true,
tabBarAccessibilityLabel: translate("tabsNavigator:transactionsTab"),
tabBarLabel: translate("tabsNavigator:transactionsTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="transfer"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
</Tabs>
)
}
export default function ProfileLayout() {
return (
<>
<Tabs.Screen
name="profile"
options={{
href: "/profile",
headerShown: false,
headerTitle: "Profile",
lazy: false,
tabBarAccessibilityLabel: translate("tabsNavigator:profileTab"),
tabBarLabel: translate("tabsNavigator:profileTab"),
tabBarIcon: ({ focused }) => (
<MaterialCommunityIcons
name="account-circle"
color={focused ? colors.palette.accent600 : colors.palette.neutral600}
size={tabBarIconSize}
/>
),
}}
/>
<Stack
screenOptions={{
headerShown: true,
}}
/>
</>
)
}
本文标签:
版权声明:本文标题:Expo Router: Achieve a back navigation from nested Native Stack under Tab Stack when navigating to parent router - Stack Overflo 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744843612a2628071.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论