我正在尝试从组件内部的堆栈屏幕设置导航选项,因为我需要使用屏幕上的特定操作来渲染右侧标题按钮。问题是它不起作用。 我使用的结构如下:
-StackNavigator
-MaterialTopTabNavigator
-tab1
-tab2
-tab3
当前代码:
//My navigation
<NavigationContainer initialState={initialState} ref={ref}>
<Stack.Navigator screenOptions={{ headerShown: false }}>
//some other Stacks
<Stack.Screen
name="Detail"
component={DetailTabScreen}
options={{
headerShown: true, //header works ok
headerRight: () => ( //this would work
<View style={{backgroundColor: 'red', width: 100}}/>
)
}}
/>
</Stack.Navigator>
</NavigationContainer>
我的DetailTabScreen:
const TopTab = createMaterialTopTabNavigator()
const DetailTabScreen = () => (
<StoreProvider>
<SafeAreaView style={{ flex: 1 }}>
<TopTab.Navigator
tabBarOptions={{
...options
}}
>
<TopTab.Screen
name="PlanDetail"
component={PlanDetail}
options={{
tabBarLabel: ({ color }: TabBarLabelProps) => (
<Text>Detalles</Text>
),
}}
/>
<TopTab.Screen
name="PlanChat"
component={PlanChat}
options={{
tabBarLabel: ({ color }: TabBarLabelProps) => (
<Text>Chat</Text>
),
}}
/>
<TopTab.Screen
name="Participants"
component={Participants}
options={{
tabBarLabel: ({ color }: TabBarLabelProps) => (
<Text>Participantes</Text>
),
}}
/>
</TopTab.Navigator>
</SafeAreaView>
</StoreProvider>
)
我已经尝试按照文档建议使用useLayoutEffect
设置组件内部的选项,也尝试使用useEffect
:
useLayoutEffect(() => {
props.navigation.setOptions({
headerRight: () => (//does not work
<TouchableOpacity
onPress={() => console.warn('This is a button!')}
style={{marginRight:16}}
>
<Icon name={Platform.OS === 'ios' ? 'share-apple' : 'share-google'} type="EvilIcons" style={{ color: colors.darkGreen, marginright: 16 }} />
</TouchableOpacity>
),
});
}, []);
PS:我知道隐藏标头并为标头使用自定义组件可以解决此问题,但是我想知道为什么navigation.setOptions
无法正常工作。
任何帮助,任何想法将不胜感激,谢谢!
答案 0 :(得分:1)
标签导航器本身没有任何标题。儿童内部的TopTab.Navigator将无法访问父级导航,即Stack.Navigator。您要么需要将父导航的实例传递给选项卡的子项,要么从堆栈中隐藏标题,然后在选项卡子项中创建自己的标题组件。另一个选择是将一个侦听器附加到选项卡屏幕,如下所示,然后您可以更新父堆栈的标题。
const DetailTabScreen = (props) => {
....
<TopTab.Screen
name="PlanDetail"
component={PlanDetail}
options={{
tabBarLabel: ({ color }: TabBarLabelProps) => (
<Text>Detalles</Text>
),
}}
listeners={{
tabPress: (e) => {
// Prevent default action
props.navigation.setOptions({
title: 'PlanDetail',
});
},
}}
/>
您可以找到更多详细信息here
答案 1 :(得分:0)
function SomeScreen({navigation}) {
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => <TouchableOpacity
onPress={() => console.warn('This is a button!')}
style={{marginRight:16}}>
<Icon name={Platform.OS === 'ios' ? 'share-apple' : 'share-google'}
type="EvilIcons" style={{ color: colors.darkGreen, marginright: 16 }} />
</TouchableOpacity>
});
}, [navigation]);
答案 2 :(得分:0)
This 帮助了我。 我通过 dangerouslyGetParent() 方法访问父堆栈导航器并设置它的选项来解决它。
useLayoutEffect(() => {
const stackNavigator = props.navigation.dangerouslyGetParent(); // this is what you need
if (stackNavigator) {
stackNavigator.setOptions({
headerRight: () => (
<TouchableOpacity
onPress={() => console.warn("This is a button!")}
style={{ marginRight: 16 }}
>
<Icon
name={Platform.OS === "ios" ? "share-apple" : "share-google"}
type="EvilIcons"
style={{ color: colors.darkGreen, marginright: 16 }}
/>
</TouchableOpacity>
),
});
}
}, []);