Profile header displayed in the ‘Settings’ tab instead of the settings header – React Native/Expo

huangapple go评论54阅读模式
英文:

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:

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 }) =&gt; (
&lt;SettingsStack.Navigator&gt;
&lt;SettingsStack.Screen
name=&quot;SettingsList&quot;
children={(props) =&gt; &lt;SettingsList {...props} handleLogout={handleLogout} /&gt;}
options={{ title: &#39;Settings&#39;, headerShown: true, headerTitleAlign: &#39;center&#39;, headerTintColor: &#39;white&#39;, headerStyle: { backgroundColor: &#39;black&#39; } }}
/&gt;
&lt;SettingsStack.Screen
name=&quot;SettingTab&quot;
component={SettingTab}
options={({ route }) =&gt; ({ title: route.params.settingName, headerShown: true, headerTitleAlign: &#39;center&#39;, headerTintColor: &#39;white&#39;, headerStyle: { backgroundColor: &#39;black&#39; } })}
/&gt;
&lt;/SettingsStack.Navigator&gt;
);

My ProfileStack.Screen: - The header button is a settings icon in the right corner that navigates to 'settings'

&lt;ProfileStack.Navigator&gt;
&lt;ProfileStack.Screen
name=&quot;Profile&quot;
options={({ route }) =&gt; ({
headerShown: route.name === &quot;Profile&quot;, // Only show header when route name is &#39;Profile&#39;
headerTitle: &#39;&#39;, // Set header title to an empty string
headerRight: () =&gt; (
&lt;HeaderButtons HeaderButtonComponent={CustomHeaderButton}&gt;
&lt;Item
title=&quot;Settings&quot;
iconName=&quot;settings&quot;
onPress={() =&gt; navigation.navigate(&#39;Settings&#39;)}
/&gt;
&lt;/HeaderButtons&gt;
),
})}
&gt;
{props =&gt; (
&lt;Profile
{...props}
userProfilePicture={userProfilePicture}
onChangeProfilePicture={setUserProfilePicture}
/&gt;
)}
&lt;/ProfileStack.Screen&gt;
&lt;ProfileStack.Screen
name=&quot;Settings&quot;
options={{ headerShown: false }}
&gt;
{props =&gt; &lt;Settings {...props} handleLogout={handleLogout} /&gt;}
&lt;/ProfileStack.Screen&gt;
&lt;/ProfileStack.Navigator&gt;

My AppNavigator:

const getheaderTitle = (route) =&gt; {
const routeName = route.name;
if (routeName === &#39;Home&#39;) {
return &#39;Home&#39;;
} else if (routeName === &#39;Profile&#39;) {
return &#39;Profile&#39;;
}
return &#39;&#39;; // Return an empty string if the route name is not recognized
};
const AppNavigator = ({ userProfilePicture, setUserProfilePicture, handleLogout }) =&gt; {
return (
&lt;Tab.Navigator
screenOptions={({ route }) =&gt; ({
tabBarIcon: ({ focused, color, size }) =&gt; {
let iconName;
if (route.name === &#39;Home&#39;) {
iconName = focused ? &#39;home&#39; : &#39;home&#39;;
} else if (route.name === &#39;Profile&#39;) {
iconName = focused ? &#39;person&#39; : &#39;person&#39;;
} else {
return null;
}
return &lt;MaterialIcons name={iconName} size={size} color={color} /&gt;;
},
headerTitle: getheaderTitle(route),
tabBarActiveTintColor: &#39;rgb(255, 255, 255)&#39;,
tabBarInactiveTintColor: &#39;rgb(114, 118, 122)&#39;,
tabBarStyle: { backgroundColor: &#39;rgb(0, 0, 0)&#39; },
})}
&gt;
&lt;Tab.Screen
name=&quot;Home&quot;
component={Home}
options={{
title: &#39;Home&#39;,
headerStyle: {
backgroundColor: &#39;rgb(0, 0, 0)&#39;, // Customize header background color
},
headerTintColor: &#39;white&#39;, // Customize header text color
}}
initialParams={{ userProfilePicture }}
/&gt;
&lt;Tab.Screen
name=&quot;Profile&quot;
children={() =&gt; (
&lt;ProfileStackScreen
userProfilePicture={userProfilePicture}
setUserProfilePicture={setUserProfilePicture}
handleLogout={handleLogout}
/&gt;
)}
options={({ route }) =&gt; ({
title: &#39;Profile&#39;,
headerTitle: getheaderTitle(route),
headerStyle: {
backgroundColor: &#39;rgb(0, 0, 0)&#39;, // Customize header background color
},
})}
/&gt;
&lt;/Tab.Navigator&gt;
);

答案1

得分: 0

你遇到的问题是由于你的导航结构造成的。你在ProfileStack.NavigatorSettingsStack.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 = () =&gt; (
&lt;RootStack.Navigator&gt;
&lt;RootStack.Screen name=&quot;AppTabs&quot; component={AppNavigator} options=. 
{{headerShown: false}}/&gt;
&lt;RootStack.Screen name=&quot;Settings&quot; component={Settings} /&gt;
&lt;/RootStack.Navigator&gt; );
const ProfileStack = createStackNavigator();
const ProfileStackScreen = ({ userProfilePicture, 
onChangeProfilePicture, handleLogout }) =&gt; (
&lt;ProfileStack.Navigator&gt;
&lt;ProfileStack.Screen
name=&quot;Profile&quot;
component={Profile}
initialParams={{ userProfilePicture, onChangeProfilePicture }}
options={({ navigation }) =&gt; ({
headerTitle: &#39;&#39;,
headerRight: () =&gt; (
&lt;HeaderButtons HeaderButtonComponent={CustomHeaderButton}&gt;
&lt;Item
title=&quot;Settings&quot;
iconName=&quot;settings&quot;
onPress={() =&gt; navigation.navigate(&#39;Settings&#39;)}
/&gt;
&lt;/HeaderButtons&gt;
),
})}
/&gt;
&lt;/ProfileStack.Navigator&gt; );

Remove the SettingsStack.Screen from ProfileStack.Navigator and modify the AppNavigator

const AppNavigator = ({ userProfilePicture, setUserProfilePicture, 
handleLogout }) =&gt; {
return (
&lt;Tab.Navigator
//... your code
&gt;
&lt;Tab.Screen
name=&quot;Home&quot;
//... your code
/&gt;
&lt;Tab.Screen
name=&quot;Profile&quot;
children={() =&gt; (
&lt;ProfileStackScreen
userProfilePicture={userProfilePicture}
onChangeProfilePicture={setUserProfilePicture}
handleLogout={handleLogout}
/&gt;
)}
//... your code
/&gt;
&lt;/Tab.Navigator&gt; ); };

Then in your main component where you're using your navigators, use RootStackScreen instead of AppNavigator

export default function App() {
return (
&lt;NavigationContainer&gt;
&lt;RootStackScreen /&gt;
&lt;/NavigationContainer&gt;
);
}

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.

huangapple
  • 本文由 发表于 2023年5月29日 18:45:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356672.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定