React Navigation5

React Navigation V5

Installation

  • 安裝

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

  • 更新一下 Cocoapods

npx pod-install ios

  • 在rn項目的最起始入口處加一句

import 'react-native-gesture-handler';

example:

import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
  );
}

Hello React Navigation

  • 安裝|Installing the stack navigator library.
npm install @react-navigation/stack
  • 使用
import { NavigationContainer } from '@react-navigation/native';  
import { createStackNavigator } from '@react-navigation/stack';
// code
<NavigationContainer>
  <Stack.Navigator>
    <Stack.Screen name="Home" component={HomeScreen} />
  </Stack.Navigator>
</NavigationContainer>
    

createStackNavigator 是一個方法,返回一個對象,這個對象有兩個屬性:Screen、Navigator,他們都是用來配置路由的react 組建,Navigator 應該包含Screen的elements來配置路由 NavigationContainer 是用來管理導航樹和導航狀態的容器組建,該組件必須封裝所有導航器結構

example

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() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
	<Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen}  options={{ title: 'Overview' }}/>
        // 這裏的DetailsScreen 頁面 沒有寫
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

initialRouteName 初始化起始頁面

頁面跳轉

// 跳轉到某個頁面,如Setting頁面,不過跳轉多少次,僅會打開一次這個頁面,
// 如果在當前頁面跳轉,沒有效果

this.props.navigation.navigate('Setting')
// 跳轉到某個頁面,如Setting頁面,跳轉多次會打開多個Setting頁面,
// 在Setting頁面跳轉會再次打開這個頁面
this.props.navigation. push('Setting')
// 返回上一個頁面
navigation.goBack()
// 返回到某一個頁面,如Home頁面,注意不要用push
navigate('Home') 
// 返回到第一個頁面
navigation.popToTop()

跳轉參數處理

// 傳參
navigation.navigate('Details', {
	itemId: 86,
	otherParam: 'anything you want here',
});
// 取參
const { itemId, otherParam } = route.params;
// 更新參數
navigation.setParams({
  query: 'someText',
})
// 初始化默認頁面參數
<Stack.Screen
  name="Details"
  component={DetailsScreen}
  initialParams={{ itemId: 42 }}
/>

向前一個頁面傳遞參數

// home->detail->home
// 通過navigate 把參數傳遞回去
navigation.navigate({
	name: 'Home',
	params: { post: postText },
	merge: true,
});

導航欄配置

  • 設置導航欄標題
// options 中的titlte

<Stack.Navigator>
  <Stack.Screen
    name="Home"
    component={HomeScreen}
    options={{ title: 'My home' }}
  />
  <Stack.Screen
    name="Profile"
    component={ProfileScreen}
    options={({ route }) => ({ title: route.params.name })}
  />
</Stack.Navigator>
    
// navigation.setOptions 設置title
this.props.navigation.setOptions({ title: 'Updated!' })
  • 導航欄樣式
    • headerStyle 導航欄樣式
    • headerTintColor 導航欄標題顏色
    • headerTitleStyle 導航欄標題樣式
<Stack.Navigator>
  <Stack.Screen
    name="Home"
    component={HomeScreen}
    options={{
      title: 'My home',
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    }}
  />
</Stack.Navigator>
  • screenOptions 配置公共導航欄樣式
    • headerStyle、headerTitleStyle、headerTintColor 同上
<NavigationContainer>
    <Stack.Navigator
        initialRouteName={'Home'}
        screenOptions={{
	        headerStyle: {
	            backgroundColor: '#00FF00',
	        },
	        headerTintColor: '#fff',
	        headerTitleStyle: {
	            fontWeight: 'bold',
	        },
    }}>
        <Stack.Screen name="Home" component={HomePage} options={{
            title: 'My home',
            headerStyle: {
                backgroundColor: '#f4511e',
            },
            headerTintColor: '#fff',
            headerTitleStyle: {
                fontWeight: 'bold',
            },
        }} />
        <Stack.Screen name="Setting" component={SettingPage} options={{ title: 'Overview' }}/>
    </Stack.Navigator>
</NavigationContainer>
  • 用自定義組件替換標題

headerTitle 接受一個組件,替換導航欄標題

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>
  );
}

導航欄按鈕

// headerRight 接受一個方法,方法返回組件,可以用來在右邊放按鈕、或者其他的...
// 注意headerRight 接受的方法中的this並不指向組件的this

<Stack.Screen
    name="Setting"
    component={SettingPage}
    options={{
        headerTitle: null,
        headerRight:() => (
            <View
                style={{
                    width:30,
                    height:30,
                    marginRight:15,
                    backgroundColor:'green'
                }}
            />
        )
    }}
/>

// 可以在組件中使用setOptions,從而指向this,也可以使用hook...(更多的可以動動腦,或者查閱相關資料)
componentDidMount() {
        this.props.navigation.setOptions({
            headerRight: this._getRightBtn,
        })
    }

_getRightBtn=()=>{
    return (
        <Button onPress={() => {
            this.setState({
                count:5
            })
        }} title="Update count11" />
    )
}
  • headerBackTitle 自定義返回按鈕的文案
  • headerBackImage 自定義返回按鈕的圖片
  • headerLeft 自定義返回按鈕 ,參考headerRight
  • headerTitle 自定義標題部分的視圖

Nesting navigators 嵌套導航欄

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

路由嵌套如下

  • Stack.Navigator
    • Home (Tab.Navigator)
      • Feed (Screen)
      • Messages (Screen)
    • Profile (Screen)
    • Settings (Screen)

嵌套路由的跳轉

navigation.navigate('Root', {
  screen: 'Settings',
  params: {
    screen: 'Sound',
    params: {
      screen: 'Media',
    },
  },
});

headerShown 在嵌套路由器中,會存在部分頁面導航欄需要隱藏,是有這個headerShown:false來隱藏導航欄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章