在react-native项目目录下,安装react-navigation包
npm install --save react-navigation
然后再安装react-native-gesture-handler包
npm install --save react-native-gesture-handler
link所有原生依赖
react-native link react-native-gesture-handler
react-native-gesture-handler在 Android 上的安装,还需要手动修改 MainActivity.java (./android/app/src/main/java/com/newpro)文件
package com.reactnavigation.newpro;
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 "newpro";
}
+ @Override
+ protected ReactActivityDelegate createReactActivityDelegate() {
+ return new ReactActivityDelegate(this, getMainComponentName()) {
+ @Override
+ protected ReactRootView createRootView() {
+ return new RNGestureHandlerEnabledRootView(MainActivity.this);
+ }
+ };
+ }
}
createStackNavigator是一个返回 React 组件的方法。 它需要 a route configuration object(一个路由配置对象) 和 an options object(一个可选对象) (现在我们忽略下面的内容). 由于 createStackNavigator 函数会返回一个React组件,因此我们可以直接从 App.js 中导出它以用作我们应用程序的根组件。
只有唯一一个路由配置:
如果只有唯一一个路由,则直接对Home进行赋值{ Home: HomeScreen }
import React from "react";
import { View, Text } from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";
class HomeScreen extends React.Component {
render() {
return (
Home Screen
);
}
}
const AppNavigator = createStackNavigator({ Home: HomeScreen });
export default createAppContainer(AppNavigator);
多个路由配置:
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createAppContainer, createStackNavigator, StackActions, NavigationActions } from 'react-navigation'; // Version can be specified in package.json
class HomeScreen extends React.Component {
render() {
return (
Home Screen
);
}
}
class DetailsScreen extends React.Component {
render() {
return (
Details Screen
);
}
}
const AppNavigator = createStackNavigator({
Home: {
screen: HomeScreen,
},
Details: {
screen: DetailsScreen,
},
}, {
initialRouteName: 'Home',
});
export default createAppContainer(AppNavigator);
情况1:navigate
this.props.navigation.navigate('Details')
如果重复多次跳到这个页面,这个页面是不会发生变化的,因为这里已经有这个路由了,你再去访问相同的路由,是不会有任何变化的
情况2:push
this.props.navigation.push('Details')
如果是直接push的话,就不会去考虑原先有没有这个路由,都是直接再次添加一个新的路由进去的
情况3:返回
返回上一个页面
this.props.navigation.goBack();
或:
this.props.navigation.pop();
返回到堆栈中的第一个页面
this.props.navigation.popToTop()
A跳转到B
A页面点击事件:
this.props.navigation.push('Details', {
testId: 123
})
B页面获取A中带入的参数:
{this.props.navigation.getParam('testId')}
或:
{this.props.navigation.state.params.testId}
改变传到B页面的参数:
this.props.navigation.setParams({
testId: '321'
})
标题样式有三个关键属性:headerStyle、headerTintColor和headerTitleStyle
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: 'white',
headerTintStyle: {
fontWeight: 'bold',
}
};
在APP.js中添加defaultNavigationOptions属性,如下:
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createAppContainer, createStackNavigator, StackActions, NavigationActions } from 'react-navigation'; // Version can be specified in package.json
import HomeScreen from './Router/HomeScreen'
import DetailsScreen from './Router/DetailsScreen'
import News from './Router/News'
const AppNavigator = createStackNavigator({
Home: {
screen: HomeScreen,
},
Details: {
screen: DetailsScreen,
},
News:{
screen: News
}
}, {
initialRouteName: 'Home',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: 'green',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
});
export default createAppContainer(AppNavigator);
这样,所有导航栏样式都公用了, 如果要改变个别导航栏样式,可以在当前页面修改
有时候,你可能需要获取上一个页面带来的参数,那么标题导航可以:
static navigationOptions = ({ navigation, navigationOptions }) => {
const { params } = navigation.state;
return {
title: params.testId+'news'
};
};
headerLeft: ({
navigation.goBack();
}}
style={{color: 'white', paddingLeft: 10}}
>
返回
)
如果要改变返回按钮的图片,则需添加headerBackImage属性
headerRight: ({
navigation.setParams({testId: '改变的新内容'})
}}
style={{color: 'white', marginRight: 10}}>
改变参数
)
整合如下:
static navigationOptions = ({ navigation, navigationOptions }) => {
const { params } = navigation.state;
return {
title: params.testId+'news',
headerLeft: ({
navigation.goBack();
}}
style={{color: 'white', paddingLeft: 10}}
>
返回
),
headerRight: ({
navigation.setParams({testId: '改变的新内容'})
}}
style={{color: 'white', marginRight: 10}}>
改变参数
)
};
};
有时候,我们的右侧按钮是要改变当前页面的state值,但是这里我们并不能直接访问到页面的state值,这里我们可以利用setParams和getParam来处理,如下:
import React from 'react';
import { View, Text, Button } from 'react-native';
class DetailsScreen extends React.Component {
state = {
count: 0
}
static navigationOptions = ({ navigation, navigationOptions }) => {
const { params } = navigation.state;
return {
title: params.testId+'news',
headerLeft: ({
navigation.goBack();
}}
style={{color: 'white', paddingLeft: 10}}
>
返回
),
headerRight: (
计数
)
};
};
addCount = () => {
this.setState({
count: this.state.count+1
})
}
componentDidMount(){
this.props.navigation.setParams({
getCount: this.addCount
})
}
render() {
const { navigation } = this.props;
console.log(navigation)
return (
Details Screen
计数大小: {this.state.count}
{navigation.getParam('testId')}
{navigation.state.params.testId}
{
navigation.setParams({
testId: '321'
})
}}>
改变参数
{
this.props.navigation.navigate('News')
}}>News Screen
{
this.props.navigation.goBack();
}}>返回goback
{
this.props.navigation.pop();
}}>返回pop
);
}
}
export default DetailsScreen
在componentDidMount中setParams一个方法,然后就可以在标题栏中调用了
import React from 'react';
import { View, Text, Button } from 'react-native';
class TitleBox extends React.Component {
render() {
return (
自定义标题
)
}
}
class News extends React.Component {
static navigationOptions = {
headerTitle:
};
render() {
return (
News Screen
{
this.props.navigation.popToTop()
}}>返回首页
);
}
}
export default News
static navigationOptions = {
header: null
};
属性:
activeTintColor -活动选项卡的标签和图标颜色。
activeBackgroundColor -活动选项卡的背景色。
inactiveTintColor -"非活动" 选项卡的标签和图标颜色。
inactiveBackgroundColor -非活动选项卡的背景色。
showLabel -是否显示选项卡的标签, 默认值为 true。
showIcon - 是否显示 Tab 的图标,默认为false。
style -选项卡栏的样式对象。
labelStyle -选项卡标签的样式对象。
tabStyle -选项卡的样式对象。
allowFontScaling -无论标签字体是否应缩放以尊重文字大小可访问性设置,默认值都是 true。
adaptive - Should the tab icons and labels alignment change based on screen size? Defaults to true for iOS 11. If false, tab icons and labels align vertically all the time. When true, tab icons and labels align horizontally on tablet.
safeAreaInset - 为 组件重写 forceInset prop, 默认值:{ bottom: 'always', top: 'never' }; top | bottom | left | right 的可选值有: 'always' | 'never'。
import React from 'react';
import { createAppContainer, createBottomTabNavigator } from 'react-navigation'; // Version can be specified in package.json
import HomeScreen from './Router/HomeScreen'
import Test from './Router/block'
const TabNavigator = createBottomTabNavigator(
{
Main: HomeScreen,
Test:Test
},
{
initialRouteName: 'Main',
tabBarOptions: {
activeTintColor: 'gold',
inactiveTintColor: 'gray',
style: {
height: 50,
}
},
}
);
const AppContainer = createAppContainer(TabNavigator)
class App extends React.Component {
render() {
return (
)
}
}
export default App;
如果应用了底部导航,有些模块可能不止一个页面,这该如何处理呢?如下:
import React, {Component} from 'react';
import { View, Text, Image } from 'react-native';
import { createAppContainer, createStackNavigator, createBottomTabNavigator } from 'react-navigation'; // Version can be specified in package.json
import HomeScreen from './Router/HomeScreen'
import DetailsScreen from './Router/DetailsScreen'
import News from './Router/News'
import Test from './Router/block'
const AppNavigator = createStackNavigator({
Home: {
screen: HomeScreen,
},
Details: {
screen: DetailsScreen,
},
News:{
screen: News
}
},
{
initialRouteName: 'Home',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: 'green',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
}
);
const TabNavigator = createBottomTabNavigator(
{
Main: {
screen: AppNavigator,
navigationOptions: ({ navigation }) => {
return {
tabBarLabel:'主页面',
tabBarIcon: ({ focused }) => {
return (
)
}
}
}
},
Test:{
screen: Test,
navigationOptions: {
// 底部导航
tabBarLabel:'测试页面',
tabBarIcon: ({ focused }) => {
return (
)
}
}
}
},
{
initialRouteName: 'Main',
tabBarOptions: {
activeTintColor: 'gold',
inactiveTintColor: 'gray',
style: {
height: 50,
}
},
defaultNavigationOptions: ({ navigation }) => {
const { routeName } = navigation.state;
return {
gesturesEnabled: false
}
}
}
);
const AppContainer = createAppContainer(TabNavigator)
class App extends Component {
render() {
return (
)
}
}
export default App;
具体代码链接:https://gitee.com/hope93/react-navigation