繁体   English   中英

反应导航 | 如何从嵌套在 Stack Navigator 中的子屏幕更改 Tab Navigator 上的按钮?

[英]React Navigation | How do I change the buttons on a Tab Navigator from a child screen nested in a Stack Navigator?

我有一个看起来像这样的标签栏: 在此处输入图像描述

两个侧面按钮是堆栈导航器(学习和日志),中间按钮需要导航日志堆栈,并且根据用户在日志堆栈中的哪个屏幕,它需要说和做不同的事情。

const Tab = createBottomTabNavigator();

const TabBarIcon = ({ icon, title, focused }) => {
  return (
    <View style={styles.iconContainer}>
      <FontAwesomeIcon
        icon={icon}
        color={focused ? Colors.neutral[4] : Colors.neutral[6]}
        size={24}
        style={styles.icon}
      />
      <Text style={[styles.iconText, focused && styles.iconTextFocused]}>
        {title}
      </Text>
    </View>
  );
};

const NullScreen = () => null;

const TabNavigator = () => {
  return (
    <Tab.Navigator
      initialRouteName="Journal"
      screenOptions={({ route }) => ({
        ...defaultNavOptions,
        headerShown: false,
        tabBarStyle: { backgroundColor: Colors.neutral[3] },
        tabBarShowLabel: false,
      })}
    >
      <Tab.Screen
        name="Learn"
        component={LearnStackNavigator}
        options={{
          tabBarIcon: ({ focused }) => (
            <TabBarIcon
              focused={focused}
              title={'Learn'}
              icon={faUserGraduate}
            />
          ),
        }}
      />
      <Tab.Screen
        name="Null Screen"
        component={NullScreen}
        options={{
          tabBarButton: ({ focused }) => (
            <View
              style={{
                position: 'relative',
                bottom: 25,
                width: 80,
                height: 80,
                borderRadius: '50%',
                backgroundColor: 'grey',

                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                shadowColor: 'black',
                shadowOpacity: 0.3,
                shadowOffset: { width: 0, height: 2 },
                shadowRadius: 3,
              }}
            >
              <TouchableOpacity onPress={() => Alert.alert('hello world')}> // This is the button that I want use for useful things
                <View style={[styles.iconContainer, styles.paddingBottom10]}>
                  <FontAwesomeIcon
                    icon={faPlus}
                    color={focused ? Colors.neutral[4] : Colors.neutral[6]}
                    size={32}
                  />
                  <Text style={styles.iconText}>{'Add Sport'}</Text>
                </View>
              </TouchableOpacity>
            </View>
          ),
        }}
      />

      <Tab.Screen
        name="Journal"
        component={LogbookStackNavigator}
        options={{
          tabBarIcon: ({ focused }) => (
            <TabBarIcon focused={focused} title={'Journal'} icon={faPenAlt} />
          ),
        }}
      />
    </Tab.Navigator>
  );
};

这是 LogbookStackNavigator 的样子:

const LogbookStack = createStackNavigator();

const LogbookStackNavigator = () => {
  return (
    <LogbookStack.Navigator
      screenOptions={{
        ...defaultNavOptions,
        headerBackTitleVisible: false,
      }}
    >
      <LogbookStack.Screen
        name="Screen1"
        component={screen1Component}
        options={defaultNavOptions}
      />
      <LogbookStack.Screen
        name="Screen2"
        component={screen2Component}
        options={defaultNavOptions}
      />
      <LogbookStack.Screen
        name="Screen3"
        component={screen3Component}
        options={entryScreenOptions}
      />
      <LogbookStack.Screen
        name="Screen4"
        component={screen4Component}
        options={SaveLogbookScreenOptions}
      />
      <LogbookStack.Screen
        name="Screen5"
        component={screen1Component5}
        options={defaultNavOptions}
      />
    </LogbookStack.Navigator>
  );
};

我知道如何使用 navigation.setOptions,但它只影响直接父导航器,而不影响祖父导航器。

我尝试的另一件事是在页面本身上制作大圆圈按钮,但它始终呈现在选项卡导航器下方。 如果有办法让它在上面呈现,我想我可以使用它。 我试过'位置:'绝对'等,它总是呈现在选项卡导航器下方。 实际上,我基本上不得不在选项卡导航器中制作一个虚拟屏幕,以便在顶部给我按钮。

我需要做的是使用选项卡导航器上的大圆圈按钮,导航到 LogbookStackNavigator 中的不同屏幕。 我怎么做?

此外,我需要根据 LogbookStackNavigator 所在的屏幕将标题从“添加运动”更改为“添加”。 我怎么做?

谢谢你的帮助

终于想通了。 你必须使用 react-native-portalize。 只需将要呈现在顶部的元素包装在<Portal></Portal>. 这会将其置于底部选项卡导航器上方。

import { Portal } from 'react-native-portalize';

const FooterButton = () => {
return(
    <Portal>
      <View>
       <Text>I appear above the Tab Navigator!</Text>
      </View>
    </Portal>
);
export default FooterButton;

不要忘记将整个应用程序包装在主机中:

//In app.js
import { Host } from 'react-native-portalize';

const App = () => {
return (
    <Host>
       <NavigationContainer>
          <AppNavigator />
       </NavigationContainer>
    </Host>
)
}
export default App;

注意:门户内的元素在导航器导航到另一个屏幕时不会清除。 因此,要解决此问题,您必须仅在屏幕处于活动状态时显示门户。 值得庆幸的是,React Navigation 5+ 提供了一个 useIsFocused 钩子,可以完美地完成这个任务。

import { Portal } from 'react-native-portalize';
import { useIsFocused } from '@react-navigation/native';

const FooterButton = () => {
  const isFocused = useIsFocused();

  // Only display the button when screen is focused. Otherwise, it doesn't go away when you switch screens
  return isFocused ? (
    <Portal>
      <View style={styles.buttonContainer}>
        <View style={styles.footer}>{props.children}</View>
      </View>
    </Portal>
  ) : null;
};
export default FooterButton;

如果你想要一个模态风格的弹出窗口,你可以包装 react-native-modalize 并用 react-native-modalize 包装它

感谢 Reddit 上的 livin52 提供的解决方案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM