[英]How to Navigate from a functional component, from a screen in a tab navigator, where that tab navigator is nested in a parent stack 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 包装它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.