原本打算將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