安裝
5.X
yarn 版本
yarn add @react-navigation/native
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm 版本
npm install @react-navigation/native
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
react-native-reanimated 動(dòng)畫(huà)庫(kù)
react-native-gesture-handler 跨平臺(tái)手勢(shì)庫(kù)
react-native-screens 這個(gè)庫(kù)基本不會(huì)單獨(dú)使用,是react navigation的依賴,用原生代碼實(shí)現(xiàn)了Screen組件(可以查看pad 內(nèi) 相關(guān)代碼),讓頁(yè)面都存在在Screen上,不安裝的話,react-nvigation 會(huì)通過(guò)View實(shí)現(xiàn),性能會(huì)很差。
react-native-safe-area-context 安全區(qū)域組件庫(kù) safe-area
react-native-community/masked-view 帶蒙版的視圖
如果你的RN 版本>=0.60, linking 是自動(dòng) 你不需要 運(yùn)行 react-native link. 但是你需要 在進(jìn)行上面操作以后進(jìn)行下面操作?。。。?!
for ios
cd ios
pod install
for android
進(jìn)入文件夾android/app/build.grade,在dependencies(依賴項(xiàng))里添加代碼(react-native-screens 相關(guān))
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
在 android/app/src/main/java/下的MainActivity.java中對(duì)手勢(shì)系統(tǒng)操作
package com.swmansion.gesturehandler.react.example;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "應(yīng)用名";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
為了使得android和iOS保持一致的體驗(yàn),必須重新封裝手勢(shì)系統(tǒng)
如果還是沒(méi)有解決問(wèn)題 點(diǎn)擊此處查看
最后操作 在index.js里添加
import 'react-native-gesture-handler';
// 如果不加這一行,在開(kāi)發(fā)時(shí)是好的,在線上版本很有可能閃退。
如果要想實(shí)現(xiàn)導(dǎo)航仍然需要安裝navigator庫(kù)
三種導(dǎo)航,分別為StackNavigator棧導(dǎo)航、TabNavigator標(biāo)簽導(dǎo)航、DrawerNavigator抽屜導(dǎo)航 項(xiàng)目中需要哪種就需要安裝相關(guān)依賴
6.X
yarn 版本
yarn add @react-navigation/native
yarn add react-native-screens react-native-safe-area-context react-native-gesture-handler
npm 版本
npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context react-native-gesture-handler
for ios
cd ios
pod install
for android
進(jìn)入文件夾android/app/src/main/java/<your package name>/MainActivity.java ,添加代碼 (react-native-screens相關(guān))
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}
并且導(dǎo)入頭文件
import android.os.Bundle;
其他操作
//StackNavigator
npm install @react-navigation/stack
//TabNavigator
npm install @react-navigation/bottom-tabs
//DrawerNavigator
npm install @react-navigation/drawer
StackNavigator
1·安裝
//StackNavigator
npm install @react-navigation/stack
??
@react-navigation/stack依賴@react-native-community/masked-view所以要確保masked-view已經(jīng)安裝
介紹以及使用
createStackNavigator 返回一個(gè)實(shí)體包含了Screen 和 Navigator.他們是用來(lái)配置的navigator 的組件 ,并且Navigator組件 必須包裹著Screen組件
NavigationContainer 是一個(gè)處理Navigator樹(shù) 和navigation state,NavigationContainer必須在最外層。一般放在app.js中.
如果改變 改變某一個(gè)頁(yè)面的配置可以用 option進(jìn)行修改,統(tǒng)一修改那么用screenOptions 后面會(huì)詳細(xì)講解
//App.js
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
function HomeScreen({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.push('Details', {
itemId: 86,
otherParam: 'anything you want here',
})}/>
</View>
);
}
function DetailsScreen({navigation}) {
const { itemId, otherParam } = route.params;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>{itemId}</Text>
<Text>{otherParam}</Text>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
options={{ title: 'Overview' }}
initialParams={{ itemId: 42 }}
component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
1 傳值問(wèn)題
如果想傳遞更多其他的參數(shù)可以通過(guò)callback 形式傳遞 ,但是要注意添加了callback 需要自行添加 React.memo 或者 React.PureComponent避免沒(méi)有必要的渲染。
<Stack.Screen name="Home">
{props => <HomeScreen {...props} extraData={someData} />}
</Stack.Screen>
navigate 到某一個(gè)界面 在本界面想要跳轉(zhuǎn)本頁(yè)面 需要修改navigate為push.如果想改變參數(shù)可以通過(guò)下面固定API進(jìn)行修改 。
// 修改 Options 不會(huì)內(nèi)容不會(huì)發(fā)生修改
props.navigation.setOptions({
title: 'hhhhhhh',
})
// 修改上一級(jí)頁(yè)面?zhèn)鬟^(guò)來(lái)的 Params 每一次修改會(huì)引起組件重新渲染
props.navigation.setParams({
name: 'linzhiqinghaoshuai',
})
如果想傳遞數(shù)據(jù)到上一個(gè)頁(yè)面,舉例而言 從 DetailsScreen 返回 HomeScreen 想要攜帶數(shù)據(jù)那么返回方法 需要修改push為navigate
// Pass and merge params back to home screen
navigation.navigate({
name: 'Home',
params: { post: postText }
});
2 配置navigationBar
首先 要注意 配置 navigationBar 有兩個(gè)屬性
如果想要改變某一個(gè)頁(yè)面的配置可通過(guò)Stack.Screen節(jié)點(diǎn)里的option進(jìn)行修改,統(tǒng)一修改那么用Stack.Navigator節(jié)點(diǎn)里的screenOptions 。
-
Stack.Navigator的配置選項(xiàng)
-
initialRouteName
展示的默認(rèn)路由界面 -
screenOptions
屏幕參數(shù)設(shè)置
2-1.headerStyle:配置頂部 header view
2-2.headerTintColor: 返回按鈕和標(biāo)題的顏色
2-3.headerTitleStyle: 標(biāo)題文字的顏色 Text.
<Stack.Navigator
initialRouteName="Home" //初始化頁(yè)面、不寫(xiě)的話默認(rèn)為 第一個(gè)screen為初始化頁(yè)面
screenOptions={{
title: '我是標(biāo)題',
headerStyle: {
backgroundColor: 'red' // 背景色
},
headerTintColor: '#green',
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 20
}}}>
-
keyboardHandlingEnabled
導(dǎo)航到新頁(yè)面鍵盤(pán)是否關(guān)閉 -
mode
頁(yè)面跳轉(zhuǎn)的動(dòng)畫(huà)類型
4-1.card:使用標(biāo)準(zhǔn)的iOS和Android屏幕過(guò)渡。默認(rèn)值.
4-2.modal:由底邊往上. -
headerMode
指定標(biāo)題的呈現(xiàn)方式
5-1.float:頁(yè)面返回標(biāo)題漸變
4-2.screen:頁(yè)面返回 標(biāo)題隨屏幕一起淡入和淡出。
5-3.none:沒(méi)有標(biāo)題header bar。
-
Stack.Screen 的配置選項(xiàng)
-
options
- 1-1. title
頭部標(biāo)題 - 1-2. header
函數(shù),返回一個(gè)React Element,顯示為標(biāo)題。 - 1-3. headerShown
是顯示還是隱藏屏幕標(biāo)題。默認(rèn)情況下顯示標(biāo)題,除非將headerMode其設(shè)置為none。設(shè)置為false隱藏標(biāo)題。在特定屏幕上隱藏標(biāo)題時(shí),您可能還需要將headerModeprop設(shè)置為screen。 - 1-4. headerTitle
字符串或返回標(biāo)頭要使用的React元素的函數(shù)。默認(rèn)為 title 選項(xiàng)值. - 1-5. headerTitleAlign
對(duì)齊標(biāo)題??蛇x擇left或center。默認(rèn)為iOS-center和Android-left - 1-6. headerTitleAllowFontScaling
標(biāo)頭標(biāo)題字體是否應(yīng)縮放以符合“文本大小”輔助功能設(shè)置。默認(rèn)為false。 - 1-7. headerBackAllowFontScaling
后退按鈕標(biāo)題字體是否應(yīng)縮放以符合“文本大小”輔助功能設(shè)置。默認(rèn)為false。 - 1-8. headerBackImage
該函數(shù)返回一個(gè)React Element以在標(biāo)題的后退按鈕中顯示自定義圖像。使用函數(shù)時(shí),它將tintColor在其參數(shù)對(duì)象中接收。默認(rèn)為帶有背面圖像源的Image組件,它是平臺(tái)的默認(rèn)背面圖標(biāo)圖像(iOS上為人字形,Android上為箭頭)。 - 1-9. headerBackTitle
iOS上的后退按鈕使用的標(biāo)題字符串。默認(rèn)為上一個(gè)場(chǎng)景的headerTitle。 - 1-10. headerBackTitleVisible
為后退按鈕標(biāo)題是否可見(jiàn)提供了一個(gè)合理的默認(rèn)值,但是如果您想覆蓋它,則可以使用true或false在此選項(xiàng)中使用 - 1-11. headerTruncatedBackTitle
當(dāng)headerBackTitle屏幕上不適合顯示后退按鈕時(shí)使用的標(biāo)題字符串。"Back"默認(rèn)情況下。 - 1-12. headerRight
該函數(shù)返回一個(gè)React元素以顯示在標(biāo)題的右側(cè)。 - 1-12. headerLeft
返回React元素以顯示在標(biāo)題左側(cè)的函數(shù)。使用函數(shù)時(shí)onPress,在呈現(xiàn)時(shí)它會(huì)接收許多參數(shù)
注意可以通過(guò)navigation.setOptions改變相應(yīng)數(shù)值
- 1-1. title
-
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={({ navigation, route }) => ({
headerTitle: props => <LogoTitle {...props} />,
})}
/>
</Stack.Navigator>
);
}
function HomeScreen({ navigation }) {
const [count, setCount] = React.useState(0);
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<Button onPress={() => setCount(c => c + 1)} title="Update count" />
),
});
}, [navigation]);
return <Text>Count: {count}</Text>;
}
.....and so on 更多點(diǎn)擊查看 詳情
TabNavigator
底部導(dǎo)航條,有的app開(kāi)發(fā)的時(shí)候需要用到底部導(dǎo)航欄切換。使用方法跟StackNavigator類似。注:如果 TabNavigator 和 StackNavigator 混和使用,可以用StackNavigator 將 TabNavigator 包裹起來(lái)。
1·安裝
npm install @react-navigation/bottom-tabs
代碼演示
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import DetailsScreen from './DetailsScreen';
import HomeScreen from './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="Details" component={DetailsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;
2·TabNavigator 的配置選項(xiàng)
-
initialRouteName
首次加載時(shí)要渲染的路由名稱。
-
screenOptions
屏幕的默認(rèn)選項(xiàng)。
-
backBehavior
返回按鈕處理的行為。
-
initialRoute
返回初始標(biāo)簽
-
order
返回上一個(gè)標(biāo)簽頁(yè)(按照標(biāo)簽頁(yè)中顯示的順序)
-
history
返回上次訪問(wèn)的標(biāo)簽頁(yè)
-
lazy
默認(rèn)為true。如果為false,則所有選項(xiàng)卡都將立即呈現(xiàn)。如果為true,則僅在首次使選項(xiàng)卡處于活動(dòng)狀態(tài)時(shí)才顯示它們。注意:選項(xiàng)卡不會(huì)在后續(xù)訪問(wèn)時(shí)重新呈現(xiàn)。
-
tabBar
返回React元素
-
tabBarOptions
包含選項(xiàng)卡欄組件的配置對(duì)象。它可以包含以下屬性:
-
activeTintColor
選中標(biāo)簽的標(biāo)簽和圖標(biāo)顏色。 - **activeBackgroundColor **
選中標(biāo)簽的背景顏色。 -
inactiveTintColor
未選中標(biāo)簽的標(biāo)簽和圖標(biāo)顏色。 - **inactiveBackgroundColor **
未選中標(biāo)簽的背景顏色。 -
showLabel
是否顯示標(biāo)簽,默認(rèn)為true。 -
showIcon
是否顯示標(biāo)簽圖標(biāo),默認(rèn)為true。 -
style
標(biāo)簽欄的樣式對(duì)象。 -
labelStyle
標(biāo)簽標(biāo)簽的樣式對(duì)象。 -
labelPosition
在何處顯示與標(biāo)簽圖標(biāo)相關(guān)的標(biāo)簽標(biāo)簽。可用值為beside-icon和below-icon。默認(rèn)為beside-icon。 -
tabStyle
標(biāo)簽的樣式對(duì)象。 -
allowFontScaling
標(biāo)簽字體是否應(yīng)縮放以符合“文本大小”輔助功能設(shè)置,默認(rèn)為true。 -
adaptive
標(biāo)簽圖標(biāo)和標(biāo)簽對(duì)齊方式是否應(yīng)根據(jù)屏幕尺寸而改變?true對(duì)于iOS 11 false,默認(rèn)值為。如果,標(biāo)簽圖標(biāo)和標(biāo)簽始終垂直對(duì)齊。當(dāng)時(shí)true,標(biāo)簽圖標(biāo)和標(biāo)簽在平板電腦上水平對(duì)齊。 -
safeAreaInset
覆蓋forceInset道具。默認(rèn)為{ bottom: ‘a(chǎn)lways’, top: ‘never’ }??捎玫逆Itop | bottom | left | right隨值一起提供’always’ | ‘never’。 -
keyboardHidesTabBar
默認(rèn)為false。如果true在鍵盤(pán)打開(kāi)時(shí)隱藏標(biāo)簽欄。
-
activeTintColor
-
options
可用于配置導(dǎo)航內(nèi)的各個(gè)屏幕。支持的選項(xiàng)有:
-
title
通用標(biāo)題可以用作備用headerTitle和tabBarLabel。 -
tabBarVisible
true或false顯示或隱藏標(biāo)簽欄(如果未設(shè)置),則默認(rèn)為true。 -
tabBarIcon
給定的函數(shù){ focused: boolean, color: string, size: number }返回一個(gè)React.Node,以顯示在選項(xiàng)卡欄中。 -
tabBarLabel
顯示在選項(xiàng)卡欄中的選項(xiàng)卡的標(biāo)題字符串或給定的函數(shù)將{ focused: boolean, color: string }返回React.Node,以顯示在選項(xiàng)卡欄中。未定義時(shí),使用場(chǎng)景title。 -
tabBarButton
該函數(shù)返回一個(gè)React元素以呈現(xiàn)為選項(xiàng)卡按鈕。它包裝圖標(biāo)和標(biāo)簽并實(shí)現(xiàn)onPress。TouchableWithoutFeedback默認(rèn)情況下渲染。tabBarButton: props => <TouchableOpacity {…props} />會(huì)TouchableOpacity改為使用。 -
tabBarAccessibilityLabel
選項(xiàng)卡按鈕的輔助功能標(biāo)簽。當(dāng)用戶點(diǎn)擊選項(xiàng)卡時(shí),屏幕閱讀器會(huì)讀取該內(nèi)容。如果您沒(méi)有標(biāo)簽的標(biāo)簽,建議您進(jìn)行設(shè)置。 -
tabBarTestID
在測(cè)試中找到此選項(xiàng)卡按鈕的ID。 -
unmountOnBlur
離開(kāi)該屏幕時(shí)是否應(yīng)卸載該屏幕。卸載屏幕將重置屏幕中的任何本地狀態(tài)以及屏幕中嵌套導(dǎo)航器的狀態(tài)。默認(rèn)為false。
-
title
DrawerNavigator導(dǎo)航
和現(xiàn)在QQ類似導(dǎo)航
1·安裝
npm install @react-navigation/drawer
代碼演示
import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import DetailsScreen from './DetailsScreen';
import HomeScreen from './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={DetailsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
export default App;