它比您希望的要复杂,但我通过创建自定义标签栏组件得到了一些工作:
const CustomTabBar = ({
state,
navigation,
descriptors,
screenHiddenInTabs,
}) => {
return (
<View
style={{
position: 'absolute',
width: '100%',
height: '100%',
}}>
<TouchableOpacity
onPress={() => {
navigation.navigate(state.routes[0].name);
}}
style={{
position: 'absolute',
height: 30,
width: '100%',
justifyContent: 'center',
backgroundColor: 'white',
}}>
<Text style={{ padding: 5 }}>{'\u003c Back to Home'}</Text>
</TouchableOpacity>
<View
style={{
flexDirection: 'row',
backgroundColor: 'white',
height: 30,
justifyContent: 'space-around',
alignItems: 'center',
position: 'absolute',
width: '100%',
bottom: 0,
}}>
{state.routes.map((route, index) => {
const isFocused = state.index === index;
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
return route.name !== screenHiddenInTabs ? (
<TouchableWithoutFeedback onPress={onPress}>
<Text style={{ color: isFocused ? 'blue' : 'black' }}>
{label}
</Text>
</TouchableWithoutFeedback>
) : null;
})}
</View>
</View>
);
};
// Pass the CustomTabBar component to the tabBar property
function YourTabs() {
return (
<Tab.Navigator
tabBar={(props) => <CustomTabBar {...props} screenHiddenInTabs="Home" />}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Browse" component={BrowseScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
这里的想法是,我们不会在标签栏中为标签导航器中的路由呈现标签,其中路由名称等于我们添加的 screenHiddenInTabs 属性的值。
这样,如果我们将screenHiddenInTabs 属性设置为"Home",与该路由名称关联的选项卡导航器中的屏幕会在第一次渲染时显示,但不会显示为选项卡栏上的选项卡。
此自定义标签栏还实现了顶部栏,可让您返回标签导航器中的第一个屏幕,在您的情况下为主屏幕。
请注意,因为我使用绝对定位来在顶部和按钮上放置一个栏,您可能需要在选项卡导航器内的屏幕上留出额外的边距。
我在这个答案中使用了自定义标签栏:Custom Tab Bar React Navigation 5 作为我在上面创建的自定义标签栏的模板。我建议在那里查看答案,因为我已经从该栏中删除了一些功能,以使示例代码不那么冗长。