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来隐藏导航栏

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