如何在 Tab Navigator React Navigation 5 中始终设置 Stack Navigator 的第一个屏幕
How to set always first screen of Stack Navigator inside Tab Navigator React Navigation 5
响应式导航 5
我在 TabNavigator 内部构建了一个 StackNavigator,主屏幕和其他屏幕之间的导航正常。但问题是,当我从 Tab2 移动到 Tab1 时,我希望 Tab1 总是显示 StackNavigator 的第一个屏幕。
tab1
-> Stack
-screen1
-screen2
tab2
我在screen2然后移动到tab2
之后我回到 Tab1 我想一直显示屏幕 1。
我正在尝试使用
OnTabPress({navigation})=>{
navigation.navigate("stackName",{
screen: "screen1"
}).
}
它的工作,但它首先显示屏幕 2,然后导航到屏幕 1。有没有其他解决方案。
https://snack.expo.io/@usamasomy/groaning-donut
initialRouteName= "NAME"
是确保您拥有默认值的关键字
并确保相应地使用 navigate()
push()
pop()
。
首先,创建一个自定义的TabBar,这样我们就可以编写自己的函数由onPress
执行
function MyTabBar({ state, descriptors, navigation }) {
return (
<View style={{ flexDirection: 'row' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
navigation.reset({
index: 0,
routes: [{ name: 'Screen1' }],
})
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
}}
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
然后在 TabScreens
中使用 tabBar=...
覆盖 Tab.Navigator
中原来的 TabBar
然后用 index:0
调用 navigation.reset()
和 routes:{{name: 'Screen1'}}
每次按下 MyTabBar
。
const TabScreens = ()=>{
return(
<Tab.Navigator tabBar={props => <MyTabBar {...props} />} initialRouteName="Tab1Screens" >
<Tab.Screen
name = "Tab1Screens"
component = {Tab1Screens}
/>
<Tab.Screen
name = "Tab2Screens"
component = {Tab2Screens}
/>
</Tab.Navigator>
)
}
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityStates={isFocused ? ['selected'] : []}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
{label}
</Text>
</TouchableOpacity>
);
})}
</View>
);
}
这可以大大改善例如:
-some logic before `navigation.reset()`
-Accessing onPress without creating a new component
-etc..
在选项中使用 unmountOnBlur: true。
例如
<Tab.Screen
name="Stack1"
component={Stack1}
options={{
tabBarLabel: "Stack1",
unmountOnBlur: true,
}}
/>
因此,当您离开此选项卡并在 Stack1 的屏幕 2 上时,返回此选项卡时,您将始终进入此 stackNavigator 的第一个屏幕。
我有一个简单的解决方案是在
中设置initialRouteName= "screen1"
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
initialRouteName="screen1"
>
<Stack.Screen name="screen1" component={Screen1} />
<Stack.Screen name="screen2" component={Screen2} />
</Stack.Navigator>
{/** **/}
如果屏幕仍然显示第一个屏幕 2,您只需注释行 <Stack.Screen name="screen2" component={Screen2} />
并重新加载屏幕,然后删除注释行。
响应式导航 5
我在 TabNavigator 内部构建了一个 StackNavigator,主屏幕和其他屏幕之间的导航正常。但问题是,当我从 Tab2 移动到 Tab1 时,我希望 Tab1 总是显示 StackNavigator 的第一个屏幕。
tab1
-> Stack
-screen1
-screen2
tab2
我在screen2然后移动到tab2 之后我回到 Tab1 我想一直显示屏幕 1。
我正在尝试使用
OnTabPress({navigation})=>{
navigation.navigate("stackName",{
screen: "screen1"
}).
}
它的工作,但它首先显示屏幕 2,然后导航到屏幕 1。有没有其他解决方案。 https://snack.expo.io/@usamasomy/groaning-donut
initialRouteName= "NAME"
是确保您拥有默认值的关键字
并确保相应地使用 navigate()
push()
pop()
。
首先,创建一个自定义的TabBar,这样我们就可以编写自己的函数由onPress
function MyTabBar({ state, descriptors, navigation }) {
return (
<View style={{ flexDirection: 'row' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
navigation.reset({
index: 0,
routes: [{ name: 'Screen1' }],
})
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
}}
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
然后在 TabScreens
中使用 tabBar=...
覆盖 Tab.Navigator
中原来的 TabBar
然后用 index:0
调用 navigation.reset()
和 routes:{{name: 'Screen1'}}
每次按下 MyTabBar
。
const TabScreens = ()=>{
return(
<Tab.Navigator tabBar={props => <MyTabBar {...props} />} initialRouteName="Tab1Screens" >
<Tab.Screen
name = "Tab1Screens"
component = {Tab1Screens}
/>
<Tab.Screen
name = "Tab2Screens"
component = {Tab2Screens}
/>
</Tab.Navigator>
)
}
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityStates={isFocused ? ['selected'] : []}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
{label}
</Text>
</TouchableOpacity>
);
})}
</View>
);
}
这可以大大改善例如:
-some logic before `navigation.reset()`
-Accessing onPress without creating a new component
-etc..
在选项中使用 unmountOnBlur: true。 例如
<Tab.Screen
name="Stack1"
component={Stack1}
options={{
tabBarLabel: "Stack1",
unmountOnBlur: true,
}}
/>
因此,当您离开此选项卡并在 Stack1 的屏幕 2 上时,返回此选项卡时,您将始终进入此 stackNavigator 的第一个屏幕。
我有一个简单的解决方案是在
中设置initialRouteName= "screen1"<Stack.Navigator
screenOptions={{
headerShown: false,
}}
initialRouteName="screen1"
>
<Stack.Screen name="screen1" component={Screen1} />
<Stack.Screen name="screen2" component={Screen2} />
</Stack.Navigator>
{/** **/}
如果屏幕仍然显示第一个屏幕 2,您只需注释行 <Stack.Screen name="screen2" component={Screen2} />
并重新加载屏幕,然后删除注释行。