将屏幕标题更新为所选选项卡导航的标题
Update screen title to that of selected tab navigation
我正在我的应用程序中使用嵌套选项卡导航实现抽屉式导航。
目前有两个问题无法解决,求指点。我正在使用 React Navigation v6.
单击我的任何选项卡导航器链接后,我注意到我的屏幕标题始终设置为“主页”。这可以更新到当前选择的选项卡吗?
使用抽屉链接时,上次单击的选项卡似乎保持其状态,旅程看起来像
- 从主页开始(可以很好地呈现主屏幕)
- 单击用户配置文件选项卡(正确呈现用户配置文件页面)
- 然后点击抽屉中的“新书 Class”,(呈现新 Class 页面正常)
- 然后单击抽屉中的“主页”(这会呈现用户个人资料屏幕)
我制作了一份小吃,希望能展示我面临的问题https://snack.expo.dev/@richlewis14/drawer-and-tab-navigation
DrawerNavigator.js
import React, {useContext} from 'react';
import CustomDrawer from '../components/CustomDrawer.js';
import {BookNewEvent} from '../screens/events/BookNewEvent.js';
import {UserProfile} from '../screens/profile/UserProfile.js';
import BottomTabNavigator from '../navigation/BottomTabNavigator.js';
import {createDrawerNavigator} from '@react-navigation/drawer';
import Ionicons from 'react-native-vector-icons/Ionicons';
const Drawer = createDrawerNavigator();
const DrawerNavigator = ({navigation}) => {
return (
<Drawer.Navigator
drawerContent={props => <CustomDrawer {...props} />}
screenOptions={{
drawerActiveBackgroundColor: '#2B6EB5',
drawerActiveTintColor: '#fff',
drawerInactiveTintColor: '#333',
drawerLabelStyle: {marginLeft: -25, fontSize: 15},
}}>
<Drawer.Screen
name="Home"
component={BottomTabNavigator}
options={{
title: 'Home',
drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
}}
/>
<Drawer.Screen
name="BookNewEvent"
component={BookNewEvent}
options={{
title: 'Book Class',
drawerIcon: ({color}) => <Ionicons name="calendar-outline" size={22} color={color} />,
}}
/>
</Drawer.Navigator>
);
};
export default DrawerNavigator;
BottomTabNavigator.js
import React, {useContext} from 'react';
import {UserLandingPage} from '../screens/landing/UserLandingPage.js';
import {BookNewEvent} from '../screens/events/BookNewEvent.js';
import {UserProfile} from '../screens/profile/UserProfile.js';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Ionicons from 'react-native-vector-icons/Ionicons';
const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator();
const UserHomeStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={UserLandingPage}
options={{headerShown: false}}
/>
</Stack.Navigator>
);
};
const BottomTabNavigator = ({navigation}) => {
return (
<Tab.Navigator
screenOptions={{
headerShown: false,
tabBarShowLabel: false,
}}>
<Tab.Screen
name="Home2"
component={UserHomeStack}
options={{
tabBarIcon: () => <Ionicons name="home" size={22} />,
}}
/>
<Tab.Screen
name="UserBookNewEvent"
component={BookNewEvent}
options={{
tabBarIcon: () => <Ionicons name="add-circle" size={22} />,
}}
/>
<Tab.Screen
name="UserProfilePage"
component={UserProfile}
options={{
tabBarIcon: () => <Ionicons name="person" size={22} color="black" />,
}}
/>
</Tab.Navigator>
);
};
export default BottomTabNavigator;
您正在 Drawer.Navigator
中嵌套 Tab.Navigator
。将其与您的零食中的以下代码片段进行比较。
<Drawer.Screen
name="Home"
component={BottomTabNavigator}
options={{
title: 'Home',
drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
}}
/>
这不是问题,但您需要记住 nesting navigators 会更改应用程序的某些行为,例如
Each navigator has its own options.
For example, specifying a title option in a screen nested in a child navigator won't affect the title shown in a parent navigator.
我们可以通过使用 react-native 的 official documentation 中提供的代码来解决此问题,以便根据 child 导航器状态设置 parent 屏幕选项。
以下是我为解决您的标题问题所做的工作。在 BottomTabNavigator.js
:
const BottomTabNavigator = ({navigation, route}) => {
function getHeaderTitle(route) {
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
switch (routeName) {
case 'Home2':
return 'Home';
case 'UserBookNewEvent':
return 'Book Class';
case 'UserProfilePage':
return 'Profile';
}
}
React.useLayoutEffect(() => {
navigation.setOptions({ headerTitle: getHeaderTitle(route) });
}, [navigation, route]);
...
请注意,我们的 BottomTabNavigator
是 Home
-Screen 的 Drawer
的 child,因此似乎两个导航器在更新时导航到同一屏幕彼此的导航状态。这是不可能的。我们可以看到这一点,如果我们通过抽屉导航到另一个屏幕,那么它的标题现在已经更新,但是屏幕保持不变。
如果用户在 Home
屏幕上时希望通过 Tab.Navigator
导航,这样两个导航器都保持可见,那么这是可能的。如果用户通过 Drawer
导航到与 Home
- 屏幕不同的屏幕,则 Tab.Navigator
将消失。
感谢评论的讨论,这是可以接受的。解决你的第二个问题可以通过将 DrawerNavigator
中提供的 Home-screen 的道具 unmountOnBlur
设置为 true 来解决,如下所示。
<Drawer.Screen
name="Home"
component={BottomTabNavigator}
options={{
title: 'Home',
unmountOnBlur:true,
drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
}}
/>
请考虑我更新的 snack 以获得完整的工作解决方案。
我正在我的应用程序中使用嵌套选项卡导航实现抽屉式导航。
目前有两个问题无法解决,求指点。我正在使用 React Navigation v6.
单击我的任何选项卡导航器链接后,我注意到我的屏幕标题始终设置为“主页”。这可以更新到当前选择的选项卡吗?
使用抽屉链接时,上次单击的选项卡似乎保持其状态,旅程看起来像
- 从主页开始(可以很好地呈现主屏幕)
- 单击用户配置文件选项卡(正确呈现用户配置文件页面)
- 然后点击抽屉中的“新书 Class”,(呈现新 Class 页面正常)
- 然后单击抽屉中的“主页”(这会呈现用户个人资料屏幕)
我制作了一份小吃,希望能展示我面临的问题https://snack.expo.dev/@richlewis14/drawer-and-tab-navigation
DrawerNavigator.js
import React, {useContext} from 'react';
import CustomDrawer from '../components/CustomDrawer.js';
import {BookNewEvent} from '../screens/events/BookNewEvent.js';
import {UserProfile} from '../screens/profile/UserProfile.js';
import BottomTabNavigator from '../navigation/BottomTabNavigator.js';
import {createDrawerNavigator} from '@react-navigation/drawer';
import Ionicons from 'react-native-vector-icons/Ionicons';
const Drawer = createDrawerNavigator();
const DrawerNavigator = ({navigation}) => {
return (
<Drawer.Navigator
drawerContent={props => <CustomDrawer {...props} />}
screenOptions={{
drawerActiveBackgroundColor: '#2B6EB5',
drawerActiveTintColor: '#fff',
drawerInactiveTintColor: '#333',
drawerLabelStyle: {marginLeft: -25, fontSize: 15},
}}>
<Drawer.Screen
name="Home"
component={BottomTabNavigator}
options={{
title: 'Home',
drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
}}
/>
<Drawer.Screen
name="BookNewEvent"
component={BookNewEvent}
options={{
title: 'Book Class',
drawerIcon: ({color}) => <Ionicons name="calendar-outline" size={22} color={color} />,
}}
/>
</Drawer.Navigator>
);
};
export default DrawerNavigator;
BottomTabNavigator.js
import React, {useContext} from 'react';
import {UserLandingPage} from '../screens/landing/UserLandingPage.js';
import {BookNewEvent} from '../screens/events/BookNewEvent.js';
import {UserProfile} from '../screens/profile/UserProfile.js';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Ionicons from 'react-native-vector-icons/Ionicons';
const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator();
const UserHomeStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={UserLandingPage}
options={{headerShown: false}}
/>
</Stack.Navigator>
);
};
const BottomTabNavigator = ({navigation}) => {
return (
<Tab.Navigator
screenOptions={{
headerShown: false,
tabBarShowLabel: false,
}}>
<Tab.Screen
name="Home2"
component={UserHomeStack}
options={{
tabBarIcon: () => <Ionicons name="home" size={22} />,
}}
/>
<Tab.Screen
name="UserBookNewEvent"
component={BookNewEvent}
options={{
tabBarIcon: () => <Ionicons name="add-circle" size={22} />,
}}
/>
<Tab.Screen
name="UserProfilePage"
component={UserProfile}
options={{
tabBarIcon: () => <Ionicons name="person" size={22} color="black" />,
}}
/>
</Tab.Navigator>
);
};
export default BottomTabNavigator;
您正在 Drawer.Navigator
中嵌套 Tab.Navigator
。将其与您的零食中的以下代码片段进行比较。
<Drawer.Screen
name="Home"
component={BottomTabNavigator}
options={{
title: 'Home',
drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
}}
/>
这不是问题,但您需要记住 nesting navigators 会更改应用程序的某些行为,例如
Each navigator has its own options. For example, specifying a title option in a screen nested in a child navigator won't affect the title shown in a parent navigator.
我们可以通过使用 react-native 的 official documentation 中提供的代码来解决此问题,以便根据 child 导航器状态设置 parent 屏幕选项。
以下是我为解决您的标题问题所做的工作。在 BottomTabNavigator.js
:
const BottomTabNavigator = ({navigation, route}) => {
function getHeaderTitle(route) {
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
switch (routeName) {
case 'Home2':
return 'Home';
case 'UserBookNewEvent':
return 'Book Class';
case 'UserProfilePage':
return 'Profile';
}
}
React.useLayoutEffect(() => {
navigation.setOptions({ headerTitle: getHeaderTitle(route) });
}, [navigation, route]);
...
请注意,我们的 BottomTabNavigator
是 Home
-Screen 的 Drawer
的 child,因此似乎两个导航器在更新时导航到同一屏幕彼此的导航状态。这是不可能的。我们可以看到这一点,如果我们通过抽屉导航到另一个屏幕,那么它的标题现在已经更新,但是屏幕保持不变。
如果用户在 Home
屏幕上时希望通过 Tab.Navigator
导航,这样两个导航器都保持可见,那么这是可能的。如果用户通过 Drawer
导航到与 Home
- 屏幕不同的屏幕,则 Tab.Navigator
将消失。
感谢评论的讨论,这是可以接受的。解决你的第二个问题可以通过将 DrawerNavigator
中提供的 Home-screen 的道具 unmountOnBlur
设置为 true 来解决,如下所示。
<Drawer.Screen
name="Home"
component={BottomTabNavigator}
options={{
title: 'Home',
unmountOnBlur:true,
drawerIcon: ({color}) => <Ionicons name="home" size={22} color={color} />,
}}
/>
请考虑我更新的 snack 以获得完整的工作解决方案。