原本打算将React Navigation-Guides这一章内容集中写在这篇文章内的,但因为篇幅太长,阅读的时候很费劲,因此这里将Guides这一章的内容分篇来记录。首先,咱们来看看Tab navigation!html
移动应用中最多见的导航样式多是基于标签的导航。 它能够是屏幕底部的标题,也能够是标题下方的顶部(甚至代替标题)。react
本指南介绍createBottomTabNavigator。 您也可使用createMaterialBottomTabNavigator和createMaterialTopTabNavigator将选项卡添加到您的应用程序。android
在继续以前,请先安装@ react-navigation / bottom-tabs:ios
npm install @react-navigation/bottom-tabs
复制代码
yarn add @react-navigation/bottom-tabs
复制代码
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function HomeScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
复制代码
这相似于自定义stack导航器的方式—初始化tab导航器时会设置一些属性,而其余属性则能够在options中按屏幕自定义。github
// You can import Ionicons from @expo/vector-icons/Ionicons if you use Expo or
// react-native-vector-icons/Ionicons otherwise.
import Ionicons from 'react-native-vector-icons/Ionicons';
// (...)
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
复制代码
让咱们对此进行剖析:redux
有时咱们想在某些图标上添加badge。 一种常见的方法是使用一个额外的视图容器,并以绝对定位的方式设置badge元素。react-native
function IconWithBadge({ name, badgeCount, color, size }) {
return (
<View style={{ width: 24, height: 24, margin: 5 }}>
<Ionicons name={name} size={size} color={color} />
{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>
);
}
复制代码
从UI角度来看,该组件已准备就绪,可使用,可是您仍然须要找到某种方法从其余地方正确传递徽章计数,例如使用 React Context, Redux, MobX 或 event emitters.markdown
function HomeIconWithBadge(props) {
// You should pass down the badgeCount in some other ways like React Context API, Redux, MobX or event emitters.
return <IconWithBadge {...props} badgeCount={3} />;
}
复制代码
切换tab使用一样的API - navigation.navigate。
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
</View>
);
}
复制代码
一般,tab上不只显示一个页面,例如,在您的Twitter feed上,您能够点击一条推文,将会跳转到这个tab里包含的一个新页面。 您能够认为这是由于每一个tab中都有单独的导航堆栈,这正是咱们在React Navigation中建模的方式。
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
const HomeStack = createStackNavigator();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
);
}
const SettingsStack = createStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
复制代码
尝试使用独立的tab bar组件而不将其集成到您在应用程序中使用的导航库中是很常见的。在某些状况下,这很好!可是,应该警告您,这样作时可能会遇到一些使人沮丧的意外问题。
例如,React Navigation的标签导航器会为您处理Android后退按钮,而独立组件一般不会。此外,若是您(做为开发人员)须要为其调用两个不一样的API,则执行诸如“跳至该选项卡,而后转到此屏幕”之类的操做更加困难。最后,移动用户界面有许多小的设计细节,要求某些组件知道其余组件的布局或存在性-例如,若是您具备半透明的标签栏,则内容应在其下方滚动,而且滚动视图应具备插图在底部等于标签栏的高度,所以您能够看到全部内容。双击选项卡栏,应使活动导航堆栈弹出到堆栈顶部,再次进行操做应将活动滚动视图滚动到该堆栈顶部。尽管并不是全部这些行为均可以经过React Navigation开箱即用地实现,可是若是使用独立的选项卡视图组件,它们将是实现的,而且您将不会得到任何这些行为。
这部份内容主要讲的是tab navigation的使用方法,使用这个组件能够很方便的设置tab导航的结构,也易于扩展和维护,熟悉的朋友应该也有同感!在设置badge上,须要另外去研究一下,后续补充这部份内容。
喜欢的朋友,麻烦点个star哦,谢谢啦~
上一章节:RN路由-React Navigation组件5.x-基本原理(中文文档)
下一章节:RN路由-React Navigation--Drawer navigation