React Native实现点击Tabbar中间按钮弹出Modal模态视图的问题
React Native 实现Tabbar点击弹出YouTube样式模态方案
你可以按照以下步骤修改代码实现需求,效果参考:

1. 调整导航结构,新增根级模态栈
首先你需要把现有Tabs导航封装到一个根StackNavigator中,用于承载全局模态视图,避免模态被Tabbar或子页面栈遮挡:
import { createStackNavigator } from '@react-navigation/stack'; import { NavigationContainer } from '@react-navigation/native'; import { TouchableOpacity, Image, View, Text } from 'react-native'; // 先定义根栈 const RootStack = createStackNavigator(); // 定义你的Tabs导航组件,就是你原来的App组件内容 const TabNavigator = () => { return ( <Tabs.Navigator tabBarOptions={{labelStyle: {fontSize:14}, activeTintColor: 'purple', showLabel: false}}> {/* 原来的四个Tab页面保留不变 */} <Tabs.Screen name="Ventes" component={venteScreenNavigator} options={{ headerShown: false, tabBarIcon: ({ focused }) => ( <View style={{ alignItems: "center", justifyContent: "center" }}> <Image source={require("./assets/Buy.png")} resizeMode="contain" style={{ width: 25, height: 25, tintColor: focused ? "black" : "gray", }} /> </View> ), }} /> <Tabs.Screen name="Map" component={mapScreenNavigator} options={{ headerShown: false, tabBarIcon: ({ focused }) => ( <View style={{ alignItems: "center", justifyContent: "center" }}> <Image source={require("./assets/geolocalisationicone.png")} resizeMode="contain" style={{ width: 25, height: 25, tintColor: focused ? "black" : "gray", }} /> </View> ) }} /> <Tabs.Screen name="Liste" component={listeScreenNavigator} options={{ headerShown: false, tabBarIcon: ({ focused }) => ( <View style={{ alignItems: "center", justifyContent: "center" }}> <Image source={require("./assets/Document.png")} resizeMode="contain" style={{ width: 25, height: 25, tintColor: focused ? "black" : "gray", }} /> </View> ), }} /> <Tabs.Screen name="Espace" component={espaceScreenNavigator} options={{ headerShown: false, tabBarIcon: ({ focused }) => ( <View style={{ alignItems: "center", justifyContent: "center" }}> <Image source={require("./assets/monespaceicone.png")} resizeMode="contain" style={{ width: 25, height: 25, tintColor: focused ? "black" : "gray", }} /> </View> ), }} /> {/* 新增中间+号Tab项 */} <Tabs.Screen name="AddModalTrigger" component={() => null} // 不需要实际页面组件,点击直接弹模态 options={{ headerShown: false, tabBarIcon: ({ focused }) => ( <View style={{ alignItems: "center", justifyContent: "center", width: 50, height: 50, borderRadius: 25, backgroundColor: 'purple', }}> {/* 可以换成你的+号本地图片 */} <Text style={{color: 'white', fontSize: 24, fontWeight: 'bold'}}>+</Text> </View> ), // 拦截默认跳转事件,触发打开模态 tabBarButton: (props) => ( <TouchableOpacity {...props} onPress={() => { // 调用根导航打开模态 props.navigation.navigate('AddModal') }} /> ) }} /> </Tabs.Navigator> ) } // 自定义模态页面组件 const AddModal = ({navigation}) => { return ( <TouchableOpacity style={{flex:1, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'flex-end'}} activeOpacity={1} onPress={() => navigation.goBack()} // 点击空白区域关闭模态 > {/* 模态内容区域,你可以自定义你的选项布局 */} <View style={{ backgroundColor: 'white', borderTopLeftRadius: 16, borderTopRightRadius: 16, padding: 20, minHeight: 200, }}> <Text style={{fontSize: 18, fontWeight: 'bold', marginBottom: 20}}>创建内容</Text> <TouchableOpacity style={{flexDirection: 'row', alignItems: 'center', marginBottom: 16}}> <Image source={require('./assets/video.png')} style={{width: 24, height:24, marginRight: 12}} /> <Text>上传视频</Text> </TouchableOpacity> <TouchableOpacity style={{flexDirection: 'row', alignItems: 'center', marginBottom: 16}}> <Image source={require('./assets/post.png')} style={{width: 24, height:24, marginRight: 12}} /> <Text>发布动态</Text> </TouchableOpacity> <TouchableOpacity style={{flexDirection: 'row', alignItems: 'center'}}> <Image source={require('./assets/live.png')} style={{width: 24, height:24, marginRight: 12}} /> <Text>开直播</Text> </TouchableOpacity> </View> </TouchableOpacity> ) } // 最终的App根组件 export default function App() { return ( <NavigationContainer> <RootStack.Navigator screenOptions={{headerShown: false}}> {/* 普通页面:Tab导航 */} <RootStack.Screen name="MainTabs" component={TabNavigator} /> {/* 模态页面:设置为透明模态,从底部弹出 */} <RootStack.Screen name="AddModal" component={AddModal} options={{ presentation: 'transparentModal', animation: 'slide_from_bottom', }} /> </RootStack.Navigator> </NavigationContainer> ) }
2. 注意事项
- 如果你的React Navigation版本低于6.x,
presentation和animation参数需要换成对应版本的模态配置参数 - 你可以根据自己的需求调整模态内部的布局、背景透明度、弹出动画等样式
- 现有子页面栈的代码不需要修改,保持原样即可
内容的提问来源于stack exchange,提问作者Yam Re
相关产品推荐
相关产品推荐

