React Native新手求教:如何创建带可折叠下拉菜单的跳转导航栏?
Hey there! Let's get that navigation bar (with a collapsible menu if you want) set up for your React Native app. First, let's fix a tiny syntax error in your code, then build out the navigation components step by step.
第一步:修正代码里的语法问题
你的Signup和Login导入语句末尾少了闭合引号,这会导致编译报错,先把这个小问题解决掉:
import React from 'react'; import { Blogs } from './app/views/Blogs.js'; // 修复引号缺失问题 import { Signup } from './app/views/Signup.js'; import { Login } from './app/views/Login.js'; import { createAppContainer } from 'react-navigation'; import { createStackNavigator } from 'react-navigation-stack'; import { Home } from './app/views/Home.js'; const AppNavigator = createStackNavigator( { BlogsRT: { screen: Blogs }, HomeRT: { screen: Home }, SignupRT: { screen: Signup }, LoginRT: { screen: Login }, }, { initialRouteName: 'HomeRT' } ); const MyRoutes = createAppContainer(AppNavigator); export default class App extends React.Component { render() { return <MyRoutes />; } }
第二步:添加自定义顶部导航栏
接下来我们给所有页面添加统一的顶部导航栏,包含你需要的Home、Blogs、Signup、Login按钮,点击就能跳转到对应页面。
方法1:全局配置导航栏(推荐)
直接在路由配置里添加全局的导航栏样式,让所有页面自动拥有这个导航栏:
// 别忘了导入需要的原生组件 import { View, TouchableOpacity, Text } from 'react-native'; const AppNavigator = createStackNavigator( { BlogsRT: { screen: Blogs }, HomeRT: { screen: Home }, SignupRT: { screen: Signup }, LoginRT: { screen: Login }, }, { initialRouteName: 'HomeRT', defaultNavigationOptions: ({ navigation }) => ({ headerLeft: null, // 隐藏默认返回按钮(可选) headerStyle: { backgroundColor: '#f4511e' }, headerTitleStyle: { color: 'white' }, headerRight: () => ( <View style={{ flexDirection: 'row', marginRight: 10 }}> <TouchableOpacity onPress={() => navigation.navigate('HomeRT')} style={{ marginHorizontal: 10 }} > <Text style={{ color: 'white' }}>Home</Text> </TouchableOpacity> <TouchableOpacity onPress={() => navigation.navigate('BlogsRT')} style={{ marginHorizontal: 10 }} > <Text style={{ color: 'white' }}>Blogs</Text> </TouchableOpacity> <TouchableOpacity onPress={() => navigation.navigate('SignupRT')} style={{ marginHorizontal: 10 }} > <Text style={{ color: 'white' }}>Signup</Text> </TouchableOpacity> <TouchableOpacity onPress={() => navigation.navigate('LoginRT')} style={{ marginHorizontal: 10 }} > <Text style={{ color: 'white' }}>Login</Text> </TouchableOpacity> </View> ), }), } );
方法2:创建可复用的导航栏组件
如果希望更灵活地控制导航栏的使用场景,可以单独写一个导航组件,然后在每个页面里导入使用:
// app/components/NavigationBar.js import React from 'react'; import { View, TouchableOpacity, Text, StyleSheet } from 'react-native'; export const NavigationBar = ({ navigation }) => { return ( <View style={styles.navContainer}> <TouchableOpacity onPress={() => navigation.navigate('HomeRT')} style={styles.navItem} > <Text style={styles.navText}>Home</Text> </TouchableOpacity> <TouchableOpacity onPress={() => navigation.navigate('BlogsRT')} style={styles.navItem} > <Text style={styles.navText}>Blogs</Text> </TouchableOpacity> <TouchableOpacity onPress={() => navigation.navigate('SignupRT')} style={styles.navItem} > <Text style={styles.navText}>Signup</Text> </TouchableOpacity> <TouchableOpacity onPress={() => navigation.navigate('LoginRT')} style={styles.navItem} > <Text style={styles.navText}>Login</Text> </TouchableOpacity> </View> ); }; const styles = StyleSheet.create({ navContainer: { flexDirection: 'row', backgroundColor: '#f4511e', paddingVertical: 15, paddingHorizontal: 10, justifyContent: 'space-around', }, navItem: { padding: 5, }, navText: { color: 'white', fontSize: 16, }, });
然后在Home.js里使用这个组件:
import { NavigationBar } from '../components/NavigationBar'; import { View, Text } from 'react-native'; export class Home extends React.Component { render() { return ( <View style={{ flex: 1 }}> <NavigationBar navigation={this.props.navigation} /> {/* 你的Home页面内容 */} <Text>Welcome to Home Page!</Text> </View> ); } }
第三步:添加可折叠下拉菜单
如果想要一个点击展开的下拉菜单,我们可以用React Native的Modal组件来实现一个简单版本:
// app/components/NavigationBar.js import React, { useState } from 'react'; import { View, TouchableOpacity, Text, StyleSheet, Modal } from 'react-native'; export const NavigationBar = ({ navigation }) => { const [menuVisible, setMenuVisible] = useState(false); return ( <View> {/* 顶部菜单按钮 */} <View style={styles.navContainer}> <TouchableOpacity onPress={() => setMenuVisible(!menuVisible)}> <Text style={styles.menuButtonText}>☰ Menu</Text> </TouchableOpacity> </View> {/* 可折叠下拉菜单 */} <Modal visible={menuVisible} transparent={true} animationType="slide" onRequestClose={() => setMenuVisible(false)} > <View style={styles.modalContainer}> <View style={styles.menuContainer}> <TouchableOpacity onPress={() => { navigation.navigate('HomeRT'); setMenuVisible(false); }} style={styles.menuItem} > <Text style={styles.menuItemText}>Home</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { navigation.navigate('BlogsRT'); setMenuVisible(false); }} style={styles.menuItem} > <Text style={styles.menuItemText}>Blogs</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { navigation.navigate('SignupRT'); setMenuVisible(false); }} style={styles.menuItem} > <Text style={styles.menuItemText}>Signup</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { navigation.navigate('LoginRT'); setMenuVisible(false); }} style={styles.menuItem} > <Text style={styles.menuItemText}>Login</Text> </TouchableOpacity> <TouchableOpacity onPress={() => setMenuVisible(false)} style={styles.closeButton} > <Text style={styles.closeButtonText}>Close</Text> </TouchableOpacity> </View> </View> </Modal> </View> ); }; const styles = StyleSheet.create({ navContainer: { backgroundColor: '#f4511e', paddingVertical: 15, paddingHorizontal: 15, }, menuButtonText: { color: 'white', fontSize: 18, }, modalContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.5)', }, menuContainer: { width: '80%', backgroundColor: 'white', borderRadius: 10, padding: 20, }, menuItem: { paddingVertical: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, menuItemText: { fontSize: 16, }, closeButton: { marginTop: 20, alignItems: 'center', }, closeButtonText: { color: '#f4511e', fontSize: 16, }, });
点击导航栏的"☰ Menu"按钮,就会弹出一个半透明背景的下拉菜单,点击选项后会自动跳转到对应页面并关闭菜单。
小提醒:react-navigation-stack是旧版本的导航库,官方现在更推荐使用@react-navigation/native配合@react-navigation/native-stack,如果是新项目可以考虑迁移,但上面的方案完全适配你当前的代码版本~
内容的提问来源于stack exchange,提问作者user3359964

