React Native应用Material TopBar与BottomBar显示及样式问题求助
解决方案:同时显示Material顶部操作栏与底部标签栏并适配React Native Paper样式
核心问题分析
- 导航栏无法同时显示:你之前将顶部和底部导航栏作为Stack导航器的独立Screen,导致只能切换显示,而非同时渲染。
- TopBar无Paper样式:误用了
createMaterialTopTabNavigator(这是标签切换组件),而非React Native Paper官方的顶部操作栏组件AppBar。
步骤1:重构导航结构
将顶部操作栏与底部标签栏整合为一个主布局组件,让Stack导航器仅负责全局页面(登录、设置等)与主布局的切换。
修改后的Bars.js
import * as React from 'react'; import { View, StyleSheet } from 'react-native'; import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs'; import { AppBar, IconButton } from 'react-native-paper'; import { MainFeed } from '../Feeds/Home'; import { SocialFeed } from '../Feeds/SocialFeed'; import { FoodFeed } from '../Feeds/FoodFeed'; import { TutoringFeed } from '../Feeds/TutoringFeed'; import { GigWorkFeed } from '../Feeds/GigworkFeed'; import { Portal, FAB } from 'react-native-paper'; const Tab = createMaterialBottomTabNavigator(); // 底部标签导航栏 export const BottomTabs = () => { return ( <React.Fragment> <Tab.Navigator shifting={true} sceneAnimationEnabled={true} barStyle={{ backgroundColor: '#6200ee' }} // 自定义BottomBar Paper样式 > <Tab.Screen name="Home" component={MainFeed} options={{ tabBarIcon: 'home' }} /> <Tab.Screen name="Social" component={SocialFeed} options={{ tabBarIcon: 'account-group' }} /> <Tab.Screen name="Food" component={FoodFeed} options={{ tabBarIcon: 'food' }} /> <Tab.Screen name="Tutoring" component={TutoringFeed} options={{ tabBarIcon: 'notebook' }} /> <Tab.Screen name="GigWork" component={GigWorkFeed} options={{ tabBarIcon: 'briefcase' }} /> </Tab.Navigator> <Portal> <FAB icon="plus" style={{ position: 'absolute', bottom: 150, right: 16, borderRadius: 50 }} /> </Portal> </React.Fragment> ); }; // 顶部操作栏(适配Paper样式) export const TopBar = ({ navigation }) => { return ( <AppBar.Header> <AppBar.Content title="我的应用" /> <IconButton icon="account-circle" onPress={() => {/* 跳转到个人资料页面逻辑 */}} /> <IconButton icon="cog" onPress={() => navigation.navigate('Settings')} /> </AppBar.Header> ); }; // 主布局:同时渲染TopBar与BottomTabs export const MainLayout = ({ navigation }) => { return ( <View style={styles.container}> <TopBar navigation={navigation} /> <BottomTabs /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, });
步骤2:调整全局Stack导航器
让Stack导航器管理登录、设置等全屏页面,主布局作为一个独立Screen嵌入其中。
修改后的App.js
import { Provider as PaperProvider } from "react-native-paper"; import { LoginScreen } from "./App/Screens/Login/login.screen"; import { SignUpScreen } from "./App/Screens/SignUp/signup.screen"; import { Settings } from "./App/Screens/Settings/settings.screen"; import { Password } from "./App/Screens/Settings/password.screen"; import { Dob } from "./App/Screens/Settings/dob.screen"; import { EmailChange } from "./App/Screens/Settings/email.screens"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { withAuthenticator } from "aws-amplify-react-native"; import Amplify from "@aws-amplify/core"; import awsConfig from "./aws-exports"; import awsmobile from "./aws-exports"; import { MainLayout } from "./App/Screens/Navigation/Bars"; Amplify.configure({ ...awsConfig, ...awsmobile, Analytics: { disabled: true } }); const Stack = createNativeStackNavigator(); const signUpConfig = { hiddenDefaults: ["phone_number"], signUpFields: [ { label: "姓名", key: "name", required: true, displayOrder: 1, type: "name", custom: false, }, ], }; function App() { return ( <PaperProvider> <NavigationContainer> <Stack.Navigator screenOptions={{ headerShown: false }} // 隐藏Stack默认头部,使用自定义TopBar > {/* 登录注册页面 */} <Stack.Screen name="Login" component={LoginScreen} /> <Stack.Screen name="SignUp" component={SignUpScreen} /> {/* 主页面:包含TopBar与BottomBar */} <Stack.Screen name="Main" component={MainLayout} /> {/* 设置相关页面 */} <Stack.Screen name="Settings" component={Settings} /> <Stack.Screen name="Password" component={Password} /> <Stack.Screen name="Dob" component={Dob} /> <Stack.Screen name="EmailChange" component={EmailChange} /> </Stack.Navigator> </NavigationContainer> </PaperProvider> ); } export default withAuthenticator(App, { signUpConfig, includeGreetings: true});
关键改进点
- 同时显示两个导航栏:
MainLayout通过View容器将TopBar与BottomTabs垂直排列,flex:1确保底部标签栏占满剩余屏幕空间,实现同时显示。 - TopBar适配Paper样式:使用React Native Paper官方的
AppBar组件,自动继承Paper主题样式,无需额外配置;通过IconButton快速添加操作按钮。 - 清晰的导航层级:Stack导航器仅负责全局页面切换,主布局内部管理底部标签页,逻辑更清晰。
内容的提问来源于stack exchange,提问作者dexter27
相关产品推荐
相关产品推荐

