本篇是React Navigation 5.0系列的第二篇文章,了解一下APP开发中常见的底部导航菜单的使用,即本文的主角:TabNavigation。本篇文章在React Navigation5.0系列一:StackNavigator的使用此篇文章的基础进行延伸,通过一系列文章构建完整的APP导航框架。
安装
使用底部导航菜单第一步要先通过如下命令行安装依赖:
yarn add @react-navigation/bottom-tabs
使用
首先我们创建如下三个基础的页面,分别是HomeScreen, SettingsScreen以及DetailScreen,具体的代码我贴在下面,基本上就是最基础的页面。
HomeScreen.js
const HomeScreen = ({ navigation }) => { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>HomeScreen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Detail')} /> </View> ) }
SettingsScreen.js
const SettingsScreen = ({ navigation }) => { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>SettingScreen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Detail')} /> </View> ) }
DetailScreen.js
const DetailScreen = ({ navigation }) => { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>DetailScreen</Text> <Button title="Go to Detail Again" // onPress={() => navigation.navigate('Detail')} onPress={() => navigation.push('Detail')} /> <Button title="Go to Home" onPress={() => navigation.navigate('Home')} /> <Button title="Go back" onPress={() => navigation.goBack()} /> <Button title="Go back to first screen in stack" onPress={() => navigation.popToTop()} /> </View> ) }
接下,我们创建底部的导航Tab路由
const TabScreen = () => { return ( <Tab.Navigator headerMode='none'> <Tab.Screen name="Home" component={HomeScreen} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> ) }
然后,我们需要创建Stack导航和Tab导航的实例对象
const Tab = createBottomTabNavigator(); const RootStack = createStackNavigator();
最后,需要添加到NavigationContainer中
const App = () => { return ( <NavigationContainer> <RootStack.Navigator initialRouteName={'TabNav'}> <RootStack.Screen name='TabNav' component={TabScreen} /> </RootStack.Navigator> </NavigationContainer> ); }
做完以上工作后,我们运行一下代码看一下效果吧。
优化
虽然上述的步骤实现了底部导航,但是和我们平时项目中看到的还是不一样,接下我们加上图标和badge.
首先创建一个带角标的icon组件
function IconWithBadge({ icon, badgeCount, size }) { return ( <View style={{ width: 24, height: 24, margin: 5 }}> <Image source={icon} style={{ width: size, height: size }} /> {badgeCount > 0 && ( <View style={{ // On React Native < 0.57 overflow outside of parent will not work on Android, see https://git.io/fhLJ8 position: 'absolute', right: -6, top: -3, backgroundColor: 'red', borderRadius: 6, width: 12, height: 12, justifyContent: 'center', alignItems: 'center', }} > <Text style={{ color: 'white', fontSize: 10, fontWeight: 'bold' }}> {badgeCount} </Text> </View> )} </View> ); }
这个组件现在就一个封装完成了,可能你在其他地方也会用到这个组件,所以为了达到组件的复用,我们再进行进一步的封装。
function HomeIconWithBadge(props) { return <IconWithBadge {...props} badgeCount={3} />; }
接下来将我们封装好的组件,添加到TabNavigation的screenOptions属性中,代码如下
const TabScreen = () => { return ( <Tab.Navigator headerMode='none' screenOptions={({ route }) => ({ tabBarIcon: ({ focused, color, size }) => { if (route.name === 'Home') { return ( <HomeIconWithBadge icon={ focused ? HomeIconActive : HomeIconNormal } size={size} color={color} /> ); } else if (route.name === 'Settings') { return ( <Image source={focused ? WorkIconActive : WorkIconNormal} style={{width: size, height: size}} /> ); } }, })} tabBarOptions={{ activeTintColor: 'tomato', inactiveTintColor: 'gray', }} > <Tab.Screen name="Home" component={HomeScreen} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> ) }
配置完成之后,我们看下最新的效果
现在和我们平时所看的APP的底部导航就差不多了😃。
TabNavigation相关属性介绍
在上一段中,tabBarIcon用于指定底部导航的图标,从代码中可以看出来他是一个方法,回调中会返回{ focused: boolean, color: string, size: number }, 返回当前tab选项卡当前选中状态,颜色以及对应的尺寸。tabBarOptions用于设置tab选项卡组件的颜色,样式等。
其他的一些属性,大家可以通过这个链接进行深入了解:createBottomTabNavigator