Android端React Native导航栏React Navigation 2.0使用

最近在使用React Native开发Android端的一些东西,在使用导航条的时候,由于跟IOS的不一样特写此篇文章介绍一下我的使用过程

本博文中使用React Navigation是基于React Native和Redux相结合使用的前提,而且本文中使用的React Navigation是V2版本,相比较V1版本有些许差别。至于React Native和Redux的使用可以在网上搜索,有好多写的不错的博文,在这里我就不再叙述。

一、Navigator组件

首先是写Navigator的书写。这里只是用到StackNavigator组件,至于其他Navigator大同小异,如果日后有时间我再做补充。

import React, { Component } from 'react';
import {
createStackNavigator,
} from 'react-navigation'
import { connect } from 'react-redux';
import AppHome from './AppHome';
import Splash from './Splash';
import Login from './centerContent/login';
import { toastShort } from '../utils/TostUtil';

import NewsPage, {} from './centerContent/News'

import { NavigationActions } from 'react-navigation';

import { addListener} from '../utils/MyNaviRedux'

import {
Platform,
BackHandler,
BackAndroid,
StatusBar,
View
} from 'react-native';

// 路由表
const RouteConfigs = {
home: { screen: AppHome },
Splash: {
screen: Splash,
navigationOptions: {
header: null,
}
},
Login: { screen: Login },
NewsPage: { screen: NewsPage},
}

//初始页
const StackNavigatorConfigs = {
initialRouteName: 'Splash',
};

export const Navigator = createStackNavigator( RouteConfigs, StackNavigatorConfigs);

class NavigatorComponent extends Component {
constructor( props) {
super( props);
this. goBackAndroid = this. goBackAndroid. bind( this);
this. goback= this. goback. bind( this);
}

render() {
return (
< Navigator
navigation= {{
dispatch: this. props. dispatch,
state: this. props. nav,
addListener,
} }
/>
);

}
goBackAndroid() {
const { routes } = this. props. nav;
const { nav} = this. props;
const { dispatch} = this. props;
console. log( nav. index);
if ( nav. index=== 0) {
if ( this. lastBackPressed && this. lastBackPressed + 2000 >= Date. now()) {
//最近2秒内按过back键,可以退出应用。
BackAndroid. exitApp();
return false;
}
this. lastBackPressed = Date. now();
toastShort( "再按一次退出应用");
return true;
}
dispatch( NavigationActions. back())
return true;
}

goback(){
const { dispatch } = this. props;
if ( dispatch) {
dispatch(
NavigationActions. back({})
);
}
}
componentWillMount() {
if ( Platform. OS === 'android') {
BackHandler. addEventListener( 'hardwareBackPress', this. goBackAndroid);
}
}
componentWillUnmount() {
if ( Platform. OS === 'android') {
BackHandler. addEventListener( 'hardwareBackPress', this. goBackAndroid);
}
}


}

function mapStateToProps( state, ownProps) {
const { nav } = state;
return {
nav
}
}


export default connect( mapStateToProps)( NavigatorComponent);

1、首先我定义了一个路由表,一个初始化页面,并使用createStackNavigator创建Navigator 。在V2版本里面已经不再使用StackNavigator方法直接创建导航栏对象,并且注意这里使用路由表和初始化页面变量来初始化StackNavigator,否则在创建reducer的时候会出现null is not an object (evaluating 'action.routeName')这样一个错误。

2、在Navigation的V2版本中不再使用addNavigationHelpers来为Navigator中navigation属性添加方法属性,而且需要田间一个addlistener属性。这个addlistener属性必须添加,否则会有一个错误。下面来说一说addListener是怎么创建出来的。

二、为Redux的Store创建中间件

1、首先我定义了一个工具MyNaviRedux用于创建addlinstener和Store的中间件

import {
createReactNavigationReduxMiddleware,
createReduxBoundAddListener
} from 'react-navigation-redux-helpers';

// 注意: createReactNavigationReduxMiddleware 必须在 createReduxBoundAddListener 之前执行
const reactMiddleware = createReactNavigationReduxMiddleware(
     "root",
     state => state. nav,
);

const addListener = createReduxBoundAddListener( "root");

export {
reactMiddleware,
addListener
};

1、需要react-navigation-redux-helpers这个包,当然我直接使用npm install react-navigation-redux-helpers命令就将次包给安装了

2、必须强调createReactNavigationReduxMiddleware一定要在createReduxBoundAddListener之前调用,否则报错。

3、这里创建了addListener 变量,这个就是在上一步操作在初始化Navigator中需要使用addListener .

4、这里创建了Redux的Store要使用的中间件reactMiddleware ,在后面添加中间件将会使用到

2、为Redux的Store添加中间件reactMiddleware 


import { createStore, applyMiddleware} from 'redux';
import thunkMiddleware from 'redux-thunk';
import rootReducer from '../reducers/index';
import { reactMiddleware} from '../utils/MyNaviRedux'


const createStoreWithMiddleware = applyMiddleware( thunkMiddleware, reactMiddleware)( createStore);
export default function configureStore( initialState) {
     const store = createStoreWithMiddleware( rootReducer, initialState);
     return store;
}
这里只需要将上一步创建的 reactMiddleware引入,然后在 applyMiddleware ( thunkMiddleware , reactMiddleware )( createStore );方法中添加就好了。至此还差最后一步,接下来就是创建reducer。

三、创建Navigation的reducer

import { NavigationActions, StackNavigator, StackActions} from "react-navigation";

import { Navigator} from '../pages/StackNavigatorComponent';

const initialState = Navigator. router. getStateForAction( Navigator. router. getActionForPathAndParams( 'home'));

export default function NavReducer( state= initialState, action) {
let nextState;
switch ( action. type) {
case 'Login':
nextState = Navigator. router. getStateForAction(
NavigationActions. navigate({ routeName: 'Login'}),
state
);
break;
case 'main':
nextState = Navigator. router. getStateForAction(
NavigationActions. navigate({ routeName: 'AppHome'})
, state
);
break;
case 'NewsPage':
nextState = Navigator. router. getStateForAction(
NavigationActions. navigate({ routeName: 'NewsPage'})
, state
);
break;
default:
nextState = Navigator. router. getStateForAction( action, state);
break;
}
return nextState ? nextState : state;
}


  • 首先我引入了在Navigator组件中创建的Navigator对象
  • 使用跳转到home页的aciton初始化变量
  • 然后就是根据dispatch中传递过来的type类型来进行相应的跳转操作

在上一步操作完成之后需要就是将此reducer添加到Redux

import { combineReducers} from 'redux';
import login from './LoginReducer';
// import nav from './NavReducer';
import NavReducer from './NavReducer'
import GetNewsData from './NewsListDataReducer'

const rootReducer = combineReducers({
login,
nav:NavReducer,
GetNewsData
})
export default rootReducer;


在这里引入上一步操作创建的Reducer加入到rootReducer中即可。

可能遇到的错误如下:

Cannot listen for a key that isn't associated with a Redux store. First call createReactNavigationReduxMiddleware so that we know when to trigger your listener

我在讲解创建中间件的时候有说道:在工具MyNaviRedux中createReactNavigationReduxMiddleware一定要在createReduxBoundAddListener之前调用。







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值