英文:
Profile header displayed in the 'Settings' tab instead of the settings header - React Native/Expo
问题
我正在使用React Native和Expo。
我遇到一个问题,即在“设置”选项卡中显示了个人资料标题,并且在其下显示了设置标题。
期望的结果是,只有在“设置”选项卡中显示设置标题,而在个人资料选项卡中只显示个人资料标题。
我的显示设置标题的设置代码 -
const Settings = ({ handleLogout }) => (
<SettingsStack.Navigator>
<SettingsStack.Screen
name="SettingsList"
children={(props) => <SettingsList {...props} handleLogout={handleLogout} />}
options={{ title: 'Settings', headerShown: true, headerTitleAlign: 'center', headerTintColor: 'white', headerStyle: { backgroundColor: 'black' } }}
/>
<SettingsStack.Screen
name="SettingTab"
component={SettingTab}
options={({ route }) => ({ title: route.params.settingName, headerShown: true, headerTitleAlign: 'center', headerTintColor: 'white', headerStyle: { backgroundColor: 'black' } })}
/>
</SettingsStack.Navigator>
);
我的ProfileStack.Screen: - 右上角的标题按钮是一个设置图标,点击它会导航到“设置”。
<ProfileStack.Navigator>
<ProfileStack.Screen
name="Profile"
options={({ route }) => ({
headerShown: route.name === "Profile", // 只有当路由名称为“Profile”时才显示标题
headerTitle: '', // 将标题设置为空字符串
headerRight: () => (
<HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
<Item
title="Settings"
iconName="settings"
onPress={() => navigation.navigate('Settings')}
/>
</HeaderButtons>
),
})}
>
{props => (
<Profile
{...props}
userProfilePicture={userProfilePicture}
onChangeProfilePicture={setUserProfilePicture}
/>
)}
</ProfileStack.Screen>
<ProfileStack.Screen
name="Settings"
options={{ headerShown: false }}
>
{props => <Settings {...props} handleLogout={handleLogout} />}
</ProfileStack.Screen>
</ProfileStack.Navigator>
我的AppNavigator:
const getheaderTitle = (route) => {
const routeName = route.name;
if (routeName === 'Home') {
return 'Home';
} else if (routeName === 'Profile') {
return 'Profile';
}
return ''; // 如果路由名称未被识别,返回空字符串
};
const AppNavigator = ({ userProfilePicture, setUserProfilePicture, handleLogout }) => {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused ? 'home' : 'home';
} else if (route.name === 'Profile') {
iconName = focused ? 'person' : 'person';
} else {
return null;
}
return <MaterialIcons name={iconName} size={size} color={color} />;
},
headerTitle: getheaderTitle(route),
tabBarActiveTintColor: 'rgb(255, 255, 255)',
tabBarInactiveTintColor: 'rgb(114, 118, 122)',
tabBarStyle: { backgroundColor: 'rgb(0, 0, 0)' },
})}
>
<Tab.Screen
name="Home"
component={Home}
options={{
title: 'Home',
headerStyle: {
backgroundColor: 'rgb(0, 0, 0)', // 自定义标题背景颜色
},
headerTintColor: 'white', // 自定义标题文本颜色
}}
initialParams={{ userProfilePicture }}
/>
<Tab.Screen
name="Profile"
children={() => (
<ProfileStackScreen
userProfilePicture={userProfilePicture}
setUserProfilePicture={setUserProfilePicture}
handleLogout={handleLogout}
/>
)}
options={({ route }) => ({
title: 'Profile',
headerTitle: getheaderTitle(route),
headerStyle: {
backgroundColor: 'rgb(0, 0, 0)', // 自定义标题背景颜色
},
})}
/>
</Tab.Navigator>
);
};
英文:
I'm using react native and Expo.
I have an issue where the profile header is displayed in the 'settings' tab and the settings header is displayed under it.
Image:
The desired outcome is for only the settings header to be displayed in the 'settings' tab and the profile header only to be shown in the profile tab.
My settings code that is showing the settings header -
const Settings = ({ handleLogout }) => (
<SettingsStack.Navigator>
<SettingsStack.Screen
name="SettingsList"
children={(props) => <SettingsList {...props} handleLogout={handleLogout} />}
options={{ title: 'Settings', headerShown: true, headerTitleAlign: 'center', headerTintColor: 'white', headerStyle: { backgroundColor: 'black' } }}
/>
<SettingsStack.Screen
name="SettingTab"
component={SettingTab}
options={({ route }) => ({ title: route.params.settingName, headerShown: true, headerTitleAlign: 'center', headerTintColor: 'white', headerStyle: { backgroundColor: 'black' } })}
/>
</SettingsStack.Navigator>
);
My ProfileStack.Screen: - The header button is a settings icon in the right corner that navigates to 'settings'
<ProfileStack.Navigator>
<ProfileStack.Screen
name="Profile"
options={({ route }) => ({
headerShown: route.name === "Profile", // Only show header when route name is 'Profile'
headerTitle: '', // Set header title to an empty string
headerRight: () => (
<HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
<Item
title="Settings"
iconName="settings"
onPress={() => navigation.navigate('Settings')}
/>
</HeaderButtons>
),
})}
>
{props => (
<Profile
{...props}
userProfilePicture={userProfilePicture}
onChangeProfilePicture={setUserProfilePicture}
/>
)}
</ProfileStack.Screen>
<ProfileStack.Screen
name="Settings"
options={{ headerShown: false }}
>
{props => <Settings {...props} handleLogout={handleLogout} />}
</ProfileStack.Screen>
</ProfileStack.Navigator>
My AppNavigator:
const getheaderTitle = (route) => {
const routeName = route.name;
if (routeName === 'Home') {
return 'Home';
} else if (routeName === 'Profile') {
return 'Profile';
}
return ''; // Return an empty string if the route name is not recognized
};
const AppNavigator = ({ userProfilePicture, setUserProfilePicture, handleLogout }) => {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused ? 'home' : 'home';
} else if (route.name === 'Profile') {
iconName = focused ? 'person' : 'person';
} else {
return null;
}
return <MaterialIcons name={iconName} size={size} color={color} />;
},
headerTitle: getheaderTitle(route),
tabBarActiveTintColor: 'rgb(255, 255, 255)',
tabBarInactiveTintColor: 'rgb(114, 118, 122)',
tabBarStyle: { backgroundColor: 'rgb(0, 0, 0)' },
})}
>
<Tab.Screen
name="Home"
component={Home}
options={{
title: 'Home',
headerStyle: {
backgroundColor: 'rgb(0, 0, 0)', // Customize header background color
},
headerTintColor: 'white', // Customize header text color
}}
initialParams={{ userProfilePicture }}
/>
<Tab.Screen
name="Profile"
children={() => (
<ProfileStackScreen
userProfilePicture={userProfilePicture}
setUserProfilePicture={setUserProfilePicture}
handleLogout={handleLogout}
/>
)}
options={({ route }) => ({
title: 'Profile',
headerTitle: getheaderTitle(route),
headerStyle: {
backgroundColor: 'rgb(0, 0, 0)', // Customize header background color
},
})}
/>
</Tab.Navigator>
);
答案1
得分: 0
你遇到的问题是由于你的导航结构造成的。你在ProfileStack.Navigator
和SettingsStack.Navigator
中都将设置屏幕作为一部分。当你从个人资料导航到设置时,它会尝试从ProfileStack.Navigator
渲染设置屏幕,其中包括自己的标题以及来自SettingsStack.Navigator
的标题。
为了解决这个问题,你应该以一种避免嵌套相同屏幕的方式构建你的导航器。
一个简单的示例可能看起来像这样:
const RootStack = createStackNavigator();
const RootStackScreen = () => (
<RootStack.Navigator>
<RootStack.Screen name="AppTabs" component={AppNavigator} options={{ headerShown: false }} />
<RootStack.Screen name="Settings" component={Settings} />
</RootStack.Navigator>
);
const ProfileStack = createStackNavigator();
const ProfileStackScreen = ({ userProfilePicture, onChangeProfilePicture, handleLogout }) => (
<ProfileStack.Navigator>
<ProfileStack.Screen
name="Profile"
component={Profile}
initialParams={{ userProfilePicture, onChangeProfilePicture }}
options={({ navigation }) => ({
headerTitle: '',
headerRight: () => (
<HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
<Item
title="Settings"
iconName="settings"
onPress={() => navigation.navigate('Settings')}
/>
</HeaderButtons>
),
})}
/>
</ProfileStack.Navigator>
);
从ProfileStack.Navigator
中移除SettingsStack.Screen
并修改AppNavigator
如下:
const AppNavigator = ({ userProfilePicture, setUserProfilePicture, handleLogout }) => {
return (
<Tab.Navigator>
{/* ... 你的其他代码 ... */}
<Tab.Screen
name="Profile"
children={() => (
<ProfileStackScreen
userProfilePicture={userProfilePicture}
onChangeProfilePicture={setUserProfilePicture}
handleLogout={handleLogout}
/>
)}
{/* ... 你的其他代码 ... */}
/>
</Tab.Navigator>
);
};
然后在你使用导航器的主要组件中,使用RootStackScreen
而不是AppNavigator
:
export default function App() {
return (
<NavigationContainer>
<RootStackScreen />
</NavigationContainer>
);
}
这只是导航结构的粗略示例,当然,你需要根据你的应用程序的需要进行调整。
英文:
The issue you're having is due to the structure of your navigation. You have Settings screen as a part of both ProfileStack.Navigator
and SettingsStack.Navigator
. When you're navigating to Settings from Profile, it's trying to render the Settings screen from ProfileStack.Navigator
which includes its own header as well as the one from SettingsStack.Navigator
.
To fix this, you should structure your navigators in a way that avoids nesting of the same screens.
The simple example of this might look something like this:
const RootStack = createStackNavigator();
const RootStackScreen = () => (
<RootStack.Navigator>
<RootStack.Screen name="AppTabs" component={AppNavigator} options=.
{{headerShown: false}}/>
<RootStack.Screen name="Settings" component={Settings} />
</RootStack.Navigator> );
const ProfileStack = createStackNavigator();
const ProfileStackScreen = ({ userProfilePicture,
onChangeProfilePicture, handleLogout }) => (
<ProfileStack.Navigator>
<ProfileStack.Screen
name="Profile"
component={Profile}
initialParams={{ userProfilePicture, onChangeProfilePicture }}
options={({ navigation }) => ({
headerTitle: '',
headerRight: () => (
<HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
<Item
title="Settings"
iconName="settings"
onPress={() => navigation.navigate('Settings')}
/>
</HeaderButtons>
),
})}
/>
</ProfileStack.Navigator> );
Remove the SettingsStack.Screen from ProfileStack.Navigator
and modify the AppNavigator
const AppNavigator = ({ userProfilePicture, setUserProfilePicture,
handleLogout }) => {
return (
<Tab.Navigator
//... your code
>
<Tab.Screen
name="Home"
//... your code
/>
<Tab.Screen
name="Profile"
children={() => (
<ProfileStackScreen
userProfilePicture={userProfilePicture}
onChangeProfilePicture={setUserProfilePicture}
handleLogout={handleLogout}
/>
)}
//... your code
/>
</Tab.Navigator> ); };
Then in your main component where you're using your navigators, use RootStackScreen instead of AppNavigator
export default function App() {
return (
<NavigationContainer>
<RootStackScreen />
</NavigationContainer>
);
}
This is a rough example of what the navigation structure might look like, of course, you will have to adjust this to match your applications needs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论