一、簡介
React Navigation是React Native是目前最主流的屏幕頁面切換的導航方案。React Navigation 5.x版本是目前最新的穩(wěn)定版本,相對于老版本的配置方式更接近React Router,更好理解。
reactNative0.60.0以上的版本會省去很多配置,建議使用0.6以上版本
npx react-native init demo --version 0.60.0 //版本號自行定義
二、依賴安裝
// 安裝react-navigation
yarn add @react-navigation/native
// 安裝依賴庫
yarn add react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
注意:鏈接原生庫(0.60版本以上的跳過此步驟)
React Native 0.60及更高版本開始,會自動鏈接,如果你版本是0.60及以上,這一步就可以跳過;而React Native 0.59以及更低版本則需要手動鏈接,安裝react-native link。
react-native link react-native-reanimated
react-native link react-native-gesture-handler
react-native link react-native-screens
react-native link react-native-safe-area-context
安裝navigator庫
有三種導航模式可以選,分別是StackNavigator棧導航、TabNavigator標簽導航、DrawerNavigator抽屜導航,下面會分別說一下怎么使用。
//StackNavigator
npm install @react-navigation/stack
//TabNavigator
npm install @react-navigation/bottom-tabs
//DrawerNavigator
npm install @react-navigation/drawer
三、StackNavigator導航
使用教程:
1.引入組件
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
2.創(chuàng)建棧導航
createStackNavigator提供APP屏幕之間切換的能力,它是以棧的形式來管理屏幕之間的切換,新切換到的屏幕會放在棧的頂部。
const Stack = createStackNavigator();
3.將需要進行屏幕切換的組件放入棧導航里
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
4.完整代碼
app/views/LoginScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class HomeScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Home')}>
<Text >跳轉(zhuǎn)首頁</Text>
</TouchableOpacity>
</View>
)
}
}
app/views/HomeScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class HomeScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Login')}>
<Text >跳轉(zhuǎn)登陸</Text>
</TouchableOpacity>
</View>
)
}
}
App.js
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
//引入頁面模塊
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
詳細參數(shù)與配置說明
-
Stack.Navigator的配置選項
- initialRouteName
首次加載名稱 - screenOptions
屏幕的默認選項。如下示例。
- initialRouteName
<Stack.Navigator
initialRouteName="Page1" //作為初始化頁面、不寫的話默認第一個screen為初始化頁面
screenOptions={{ //用來定制頭部信息、根據(jù)自己需要更改
title: '測試標題',
headerStyle: {
backgroundColor: '#ee7530'
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 20
}
}}>
- keyboardHandlingEnabled
如果為false,則導航到新屏幕時,屏幕鍵盤不會自動關閉。默認為true - mode
定義渲染和過渡的樣式
card:使用標準的iOS和Android屏幕過渡。這是默認值.
modal:這有兩件事:設置headerMode到screen堆棧,除非指定使屏幕從iOS底部的底部滑入,這是一種常見的iOS模式. - headerMode
指定標題的呈現(xiàn)方式
float:渲染停留在頂部的單個標題,并在更改屏幕時進行動畫處理。iOS上的常見模式。
screen:每個屏幕都有一個附加的標題,標題隨屏幕一起淡入和淡出。Android上的常見模式。
none :沒有標題。
-
Stack.Screen的配置選項
options
可用于配置導航器內(nèi)的各個屏幕
title
頭部標題
function StackScreen() {
return (
// 靜態(tài)值
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'My home' }}
/>
// 動態(tài)獲取
<Stack.Screen
name="Profile"
component={HomeScreen}
options={({ route }) => ({ title: route.params.name })}
/>
</Stack.Navigator>
);
}
/* 在組件中修改使用setOptions */
<Button
title="Update the title"
onPress={() => navigation.setOptions({ title: 'Updated!' })}
/>
header
函數(shù),返回一個React Element,顯示為標題。如下示例。
header: ({ scene, previous, navigation }) => {
const { options } = scene.descriptor;
const title =
options.headerTitle !== undefined
? options.headerTitle
: options.title !== undefined
? options.title
: scene.route.name;
return (
<MyHeader
title={title}
leftButton={
previous ? <MyBackButton onPress={navigation.goBack} /> : undefined
}
style={options.headerStyle}
/>
);
};
headerShown
是顯示還是隱藏屏幕標題。默認情況下顯示標題,除非將headerMode其設置為none。設置為 false隱藏標題。在特定屏幕上隱藏標題時,您可能還需要將headerModeprop 設置為screen。
headerTitle
字符串或返回標頭要使用的React元素的函數(shù)。默認為 title 選項值.
function LogoTitle() {
return (
<Image
style={{ width: 50, height: 50 }}
source={require('@expo/snack-static/react-native-logo.png')}
/>
);
}
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ headerTitle: props => <LogoTitle {...props} /> }}
/>
</Stack.Navigator>
);
}
headerTitleAlign
對齊標題??蛇x擇left或center。默認為iOS-center和Android-left
headerTitleAllowFontScaling
標頭標題字體是否應縮放以符合“文本大小”輔助功能設置。默認為false。
headerBackAllowFontScaling
后退按鈕標題字體是否應縮放以符合“文本大小”輔助功能設置。默認為false。
headerBackImage
該函數(shù)返回一個React Element以在標題的后退按鈕中顯示自定義圖像。使用函數(shù)時,它將tintColor在其參數(shù)對象中接收。默認為帶有背面圖像源的Image組件,它是平臺的默認背面圖標圖像(iOS上為人字形,Android上為箭頭)。
headerBackTitle
iOS上的后退按鈕使用的標題字符串。默認為上一個場景的headerTitle。
headerBackTitleVisible
為后退按鈕標題是否可見提供了一個合理的默認值,但是如果您想覆蓋它,則可以使用true或false在此選項中使用
headerTruncatedBackTitle
當headerBackTitle屏幕上不適合顯示后退按鈕時使用的標題字符串。"Back"默認情況下。
headerRight
該函數(shù)返回一個React元素以顯示在標題的右側。
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerTitle: props => <LogoTitle {...props} />,
headerRight: () => (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
),
}}
/>
</Stack.Navigator>
);
}
headerLeft
返回React元素以顯示在標題左側的函數(shù)。使用函數(shù)時onPress,在呈現(xiàn)時它會接收許多參數(shù)(label,labelStyle和more-檢查types.tsx以獲取完整列表)。
headerStyle
標頭的樣式對象。例如,您可以在此處指定自定義背景色。
headerTitleStyle
標題組件的樣式對象
headerBackTitleStyle
標題的樣式對象
headerLeftContainerStyle
自定義headerLeft組件容器的樣式,例如添加填充。
headerRightContainerStyle
自定義headerRight組件容器的樣式,例如添加填充。
headerTitleContainerStyle
自定義headerTitle組件容器的樣式,例如添加填充。默認情況下,headerTitleContainerStyle是具有絕對位置的風格和偏移量都left和right。這可能導致的空白或之間重疊headerLeft和headerTitle如果定制headerLeft被使用??梢酝ㄟ^在中和中進行調(diào)整left和right樣式來解決。headerTitleContainerStylemarginHorizontalheaderTitleStyle
headerTintColor
標頭的色調(diào)顏色
headerPressColorAndroid
材料波紋的顏色(僅適用于Android> = 5.0)
headerTransparent
默認為false。如果為true,則標題將沒有背景,除非您明確為其提供背景headerBackground。標頭也將浮動在屏幕上,使其與下面的內(nèi)容重疊。
headerBackground
返回React元素以呈現(xiàn)為標題背景的函數(shù)。這對于使用背景(例如圖像或漸變)很有用。
例如,可以將其headerTransparent用于渲染模糊視圖以創(chuàng)建半透明標題。參考下述示例.
import { BlurView } from 'expo-blur';
<Screen
name="Home"
component={HomeScreen}
options={{
headerTransparent: true,
headerBackground: () => (
<BlurView tint="light" intensity={100} style={StyleSheet.absoluteFill} />
),
}}
/>;
headerStatusBarHeight
在標題頂部添加額外的填充以說明半透明的狀態(tài)欄。默認情況下,它使用設備安全區(qū)域插圖中的最大值。傳遞0或自定義值以禁用默認行為,并自定義高度。
cardShadowEnabled
使用此道具在過渡期間具有可見的陰影。默認為true。
cardOverlayEnabled
使用此道具可以在過渡期間在卡下看到半透明的深色覆蓋層。默認為trueAndroid和falseiOS。
cardStyle
堆棧中卡的樣式對象。您可以在此處提供自定義背景色,以代替默認背景。您還可以指定{ backgroundColor: ‘transparent’ }使前一個屏幕在下面可見(對于透明模式)。這對于實現(xiàn)模態(tài)對話框之類的東西很有用。mode: 'modal’使用透明背景時,還應該在堆棧視圖配置中指定,這樣以前的屏幕就不會分離并且在下面保持可見。
animationEnabled
屏幕上是否應啟用過渡動畫。如果將其設置為false,則按下或彈出時屏幕不會動畫。默認為true。
animationTypeForReplace
當此屏幕替換另一個屏幕時要使用的動畫類型。它采用以下值:
push -將使用推送新屏幕的動畫
pop -將使用彈出屏幕的動畫
默認為push。
當pop被使用時,pop動畫被施加到被替換的畫面。
gestureEnabled
是否可以使用手勢關閉此屏幕。默認為trueiOS,falseAndroid。
gestureResponseDistance
從屏幕邊緣開始覆蓋觸摸距離的對象,以識別手勢。該對象可以包含以下屬性:
horizontal- 數(shù)字 -水平方向的距離。默認為25。
vertical- 數(shù)字 -垂直方向的距離。默認值為135。
gestureVelocityImpact
決定手勢速度相關性的數(shù)字。默認值為0.3。
gestureDirection
手勢的方向。與動畫有關
transitionSpec
屏幕過渡的配置對象。與動畫有關.請點擊此處查看
cardStyleInterpolator
插卡各部分的插補樣式。與動畫有關請點擊此處查看
headerStyleInterpolator
標頭各部分的內(nèi)插樣式。與動畫有關請點擊此處查看
safeAreaInsets
屏幕的安全區(qū)域插圖。這用于避免使用諸如缺口和狀態(tài)欄之類的元素。默認情況下,將自動檢測設備的安全區(qū)域插圖。您可以使用此選項覆蓋行為。接受包含以下可選屬性的對象:
top- 數(shù)字 -頂部插圖的值,例如包含狀態(tài)欄和槽口的區(qū)域。
right- 數(shù)字 -左插圖的值。
bottom- 數(shù)字 -頂部插圖的值,例如底部的區(qū)域?qū)Ш綑凇?br>
left。- 數(shù)字 -右插圖的值。
四、TabNavigator導航
底部導航欄,有的app開發(fā)的時候需要用到底部導航欄切換。使用方法跟StackNavigator類似。
1.安裝:
npm install @react-navigation/bottom-tabs
2.完整代碼
App.js
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
//導入
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
//引入頁面模塊
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={{
activeTintColor: 'red',
inactiveTintColor: 'gray',
tabStyle : {
backgroundColor: '#ddd',
paddingBottom: 15,
borderRightWidth: 1,
borderRightColor: '#fff'
},
}}
>
<Tab.Screen name="Home" component={HomeScreen} options={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}} />
<Tab.Screen name="Login" component={LoginScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;
詳細參數(shù)與配置說明
Tab.Navigator的配置
initialRouteName
導航首次加載時要渲染的路線的名稱。screenOptions
導航中用于屏幕的默認選項。-
backBehavior
后退按鈕處理的行為。- initialRoute: 返回初始標簽
- order: 返回上一個標簽頁(按照標簽頁中顯示的順序)
- history: 返回上次訪問的標簽頁
- none:不處理后退按鈕
lazy
默認為true。如果為false,則所有選項卡都將立即呈現(xiàn)。如果為true,則僅在首次使選項卡處于活動狀態(tài)時才顯示它們。注意:選項卡不會在后續(xù)訪問時重新呈現(xiàn)。tabBar
返回React元素以顯示為選項卡欄的函數(shù)-
tabBarOptions
包含選項卡欄組件的道具的對象。它可以包含以下屬性:- activeTintColor -活動標簽的標簽和圖標顏色。
- activeBackgroundColor -活動標簽的背景顏色。
- inactiveTintColor -非活動標簽的標簽和圖標顏色。
- inactiveBackgroundColor -非活動標簽的背景顏色。
- showLabel -是否顯示標簽標簽,默認為true。
- showIcon -是否顯示標簽圖標,默認為true。
- style -標簽欄的樣式對象。
- labelStyle -標簽標簽的樣式對象。
- labelPosition-在何處顯示與標簽圖標相關的標簽標簽??捎弥禐閎eside-icon和below-icon。默認為beside-icon。
- tabStyle -標簽的樣式對象。
- allowFontScaling -標簽字體是否應縮放以符合“文本大小”輔助功能設置,默認為true。
- adaptive-標簽圖標和標簽對齊方式是否應根據(jù)屏幕尺寸而改變?true對于iOS 11 false,默認值為。如果,標簽圖標和標簽始終垂直對齊。當時true,標簽圖標和標簽在平板電腦上水平對齊。
- safeAreaInset-覆蓋forceInset道具。默認為{ bottom: ‘a(chǎn)lways’, top: ‘never’ }??捎玫逆Itop | bottom | left | right隨值一起提供’always’ | ‘never’。
- keyboardHidesTabBar-默認為false。如果true在鍵盤打開時隱藏標簽欄。
options 可用于配置導航內(nèi)的各個屏幕。支持的選項有:
- title
通用標題可以用作備用headerTitle和tabBarLabel。 - tabBarVisible
true或false顯示或隱藏標簽欄(如果未設置),則默認為true。 - tabBarIcon
給定的函數(shù){ focused: boolean, color: string, size: number }返回一個React.Node,以顯示在選項卡欄中。 - tabBarLabel
顯示在選項卡欄中的選項卡的標題字符串或給定的函數(shù)將{ focused: boolean, color: string }返回React.Node,以顯示在選項卡欄中。未定義時,使用場景title。 - tabBarButton
該函數(shù)返回一個React元素以呈現(xiàn)為選項卡按鈕。它包裝圖標和標簽并實現(xiàn)onPress。TouchableWithoutFeedback默認情況下渲染。tabBarButton: props => <TouchableOpacity {…props} />會TouchableOpacity改為使用。 - tabBarAccessibilityLabel
選項卡按鈕的輔助功能標簽。當用戶點擊選項卡時,屏幕閱讀器會讀取該內(nèi)容。如果您沒有標簽的標簽,建議您進行設置。 - tabBarTestID
在測試中找到此選項卡按鈕的ID。 - unmountOnBlur
離開該屏幕時是否應卸載該屏幕。卸載屏幕將重置屏幕中的任何本地狀態(tài)以及屏幕中嵌套導航器的狀態(tài)。默認為false。
五、DrawerNavigator導航
1.安裝:
npm install @react-navigation/drawer
2.完整代碼
App.js
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
//導入
import { createDrawerNavigator } from '@react-navigation/drawer';
//引入頁面模塊
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';
const Drawer = createDrawerNavigator();
function App() {
return (
<NavigationContainer
drawerStyle={{
backgroundColor: '#c6cbef',
width: 200,
}}
>
<Drawer.Navigator initialRouteName='Home'>
<Drawer.Screen name='Home' component={HomeScreen} />
<Drawer.Screen name='Login' component={LoginScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
export default App;
六、組合使用
原生思維是TabNavigator中嵌套StackNavigator,但是這里建議StackNavigator中嵌套TabNavigator。因為可以避免控制TabNavigator的tabbar顯示和隱藏問題。