react-navigation 使用的整体框架 安卓物理返回键

react navite 目录结构

js文件夹

  • root.js  //入口
  • api 文件夹  //存放API
  • img 文件夹  //存放图片
  • components 文件夹 //存放组件
  • router 文件夹 //存放导航页面
  1. TabNavigator
  2. AppNavigator
  • store 文件夹 //存放redux
  1. index.js  //
  2. reducers文件夹 //存放

            nav.js //在redux里存导航的状态

            index.js  //合并各个子 reduce

  • utils 文件夹 //存放工具

一、"react-navigation": "^1.0.0-beta.22" 低版本的使用

router 文件夹 下建立两个文件夹专门来写导航的页面

1、TabNavigator 专门来写Tab栏上的页面(tab栏上的每个页面的导航都可以在组件中设置,新版本的导航会统一写一个页面)

import React, { Component } from 'react';
import { TabNavigator, TabBarBottom } from 'react-navigation';

import Home from '../components/Home';
import User from '../components/User';


export default (TabNav = TabNavigator({
  Home: { screen: Home },
  User: { screen: User },
}, {
  tabBarComponent: TabBarBottom,
  tabBarPosition: 'bottom',
  showIcon: true,
  animationEnabled: true,
  swipeEnabled: false,
  tabBarOptions: {
    activeTintColor: '#3D3939',
    inactiveTintColor: '#3D3939',
  },
}));

  

Tab栏上的每个页面的导航

  static navigationOptions = {
    header: null,
    title: '首页',
    tabBarIcon: ({ focused }) => (
      <Image style={{ width:27, height: 27 }} source={focused ? require('../../img/home-selected.png') : require('../../img/home.png')} />
    ),
  }

2、AppNavigator  把所有跳转的页面都写在此页面里

import Splash from '../pages/Splash'; // app开屏画面
import TabRouter from './TabRouter'; //tab栏
import Guide from '../guide/guide'; // 引导页

export const AppNavigator = StackNavigator(
  {
    Splash: { screen: Splash },
    tab: { screen: TabRouter },
    Guide: { screen: Guide }
  }

可以再建立一个页面专门写安卓物理返回键操作(并且在tab栏上可以点击两次退出App)

import React from 'react';
import { addNavigationHelpers, StackNavigator, NavigationActions } from 'react-navigation';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { BackHandler } from "react-native";
import { AppNavigator } from "./AppNavigator";

class App extends React.Component {
  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
  }
  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
  }
  onBackPress = () => {
    const { dispatch, nav } = this.props;
    if (nav.index === 0) {
      return false;
    }
    dispatch(NavigationActions.back());
    return true;
  };

  render() {
    const { dispatch, nav } = this.props;
    const navigation = addNavigationHelpers({
      dispatch,
      state: nav,
    });

    return <AppNavigator navigation={navigation} />;
  }
}

App.propTypes = {
  dispatch: PropTypes.func.isRequired,
  nav: PropTypes.object.isRequired,
};

const mapStateToProps = state => ({
  nav: state.nav,
});

export default connect(mapStateToProps)(App);

在安卓上可以使用物理键返回需要redux集成

nav页面(存储导航状态)

import { NavigationActions } from 'react-navigation';
import { AppNavigator } from '../Routers/AppNavigator';

const initialState = AppNavigator.router.getStateForAction(NavigationActions.init());

// ---------reducer---------

export default function nav(state = initialState, action) {
  let nextState;
  if (action && action.type.indexOf('Navigation/') === 0) {
    nextState = AppNavigator.router.getStateForAction(action, state);
  }
  return nextState || state;
}

在注册页面里引用App组件,就可以实现各个页面的导航以及安卓物理键的使用

二、"react-navigation": "^2.3.0" 新版本的使用

在新版本中很有属性和方法被移除里,使用redux集成,需要下载一个插件react-navigation-redux-helpers

跟旧版本一样,都是建立两个文件存导航页面

1、TabNavigator 专门来写Tab栏上的页面

import Home from '../components/home'; // 底部:首页
import User from '../components/user'; //底部: 我的


const Home = createStackNavigator({
	Home: {
		screen: Home
		navigationOptions: () => ({
			title:  首页,
			headerBackTitle: null,
			header: null,
			headerStyle: {
				backgroundColor: '#ffffff',
				borderBottomWidth: 0
			},
			headerTitleStyle: {
				color: 'rgba(13,14,21,1)',
				fontSize: 18
			},
			headerTintColor: '#000',
			borderWidth: 0
		})
	}
});

const User = createStackNavigator({
	User: {
		screen: User,
		navigationOptions: () => ({
			title: 我的,
			headerBackTitle: null,
			header: null,
			headerStyle: {
				backgroundColor: '#ffffff',
				borderBottomWidth: 0
			},
			headerTitleStyle: {
				color: 'rgba(13,14,21,1)',
				fontSize: 18
			},
			headerTintColor: '#000'
		})
	}
});

const TabBarPage = createBottomTabNavigator(
	{
		Home: {
			screen: Home,
			navigationOptions: {
				tabBarLabel: ({ tintColor, focused }) => (
					<Text style={{ color: tintColor, fontSize: 12, textAlign: 'center' }}>首页</Text>
				),
				tabBarIcon: ({ focused, tintColor }) => <Icon name="icon-home" size={30} color={tintColor} />
				  ),

			}
		},
		User: {
			screen: My,
			navigationOptions: {
				tabBarLabel: ({ tintColor, focused }) => (
					<Text style={{ color: tintColor, fontSize: 12, textAlign: 'center' }}>我的</Text>
				),
				tabBarIcon: ({ focused, tintColor }) => <Icon name="icon-user" size={30} color={tintColor} />
				  ),
			}
		}
	},
	{
		lazy: true,
		animationEnabled: true,
		backBehavior: true,
		tabBarPosition: 'bottom',
		tabBarOptions: {
			activeTintColor: '#3e9ce9',
			inactiveTintColor: '#999999',
			showIcon: true,
			style: {
				backgroundColor: '#fff',
				height: 98
			},
			indicatorStyle: {
				opacity: 0
			},
			tabStyle: {
				padding: 0
			}
		}
	}
);

2、AppNavigator  把所有跳转的页面都写在此页面里(但是因为更新了版本,在redux集成的时候,做了更多的处理)

import Splash from '../pages/Splash'; // app开屏画面
import TabRouter from './TabRouter'; //tab栏
import Guide from '../guide/guide'; // 引导页
import { createStackNavigator } from 'react-navigation'; // 页面切换 路由导航组件
import { reduxifyNavigator, createReactNavigationReduxMiddleware, createNavigationReducer } from 'react-navigation-redux-helpers';

export const RootNavigator = createStackNavigator(
  {
    Splash: { screen: Splash },
    tab: { screen: TabRouter },
    Guide: { screen: Guide }
  }

export const middleware = createReactNavigationReduxMiddleware(
	'root',
	state => state.nav
)


const AppWithNavigationState = reduxifyNavigator(RootNavigator, 'root');

const mapStateToProps = state => ({
	state: state.nav
});
const AppNavigator = connect(mapStateToProps)(AppWithNavigationState);

可以再建立一个页面专门写安卓物理返回键操作(并且在tab栏上可以点击两次退出App)

import React from 'react';
import { NavigationActions } from 'react-navigation';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { BackHandler } from "react-native";
import { AppNavigator } from "./AppNavigator";
class App extends Component {
	componentDidMount() {
        BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
    }
    componentWillUnmount() {
        BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
    }
    onBackPress = () => {
		const { dispatch, state } = this.props;
		if(state.index === 0){
			if(this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
				Alert.alert('提示','您确定要退出吗?',[
					{text: '取消', onPress: () => {return false }},
					{text: '确定', onPress: () => { BackHandler.exitApp() }}
				  ])
			}
			this.lastBackPressed = Date.now();
			return true
			// return false;
		}
		dispatch(NavigationActions.back());
		return true;
       };
	render() {
		const { dispatch, nav } = this.props;
        // const navigation = addNavigationHelpers(); 因为addNavigationHelpers 已被移除不存在
		return <AppNavigator navigation={{
			dispatch,
			state: nav
		}} />
	}
}
export default connect(mapStateToProps)(App)

nav页面(存储导航状态)这个跟旧的一样

import { NavigationActions } from 'react-navigation';
import { AppNavigator } from '../Routers/AppNavigator';


const initialState = AppNavigator.router.getStateForAction(NavigationActions.init());

// ---------reducer---------

export default function nav(state = initialState, action) {
  let nextState;
  if (action && action.type.indexOf('Navigation/') === 0) {
    nextState = AppNavigator.router.getStateForAction(action, state);
  }
  return nextState || state;
}



reducer文件下的index页面

import { combineReducers } from 'redux';
import nav from './nav';

export default const reducers = combineReducers({
    nav
});

store文件下的index页面

import { createStore, applyMiddleware } from "redux";
import thunk from 'redux-thunk'
import logger from 'redux-logger'
import reducers from './reducers/index';
import { middleware } from "../containers/app";


const store = applyMiddleware(thunk, logger, middleware)(createStore)(reducers);

window.store = store;
export default store;
import { Provider, connect } from 'react-redux';
import React from 'react';
import App from './App';
import { middleware } from './AppNavigator';
import store from './store/index';


class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <App />
      </Provider>
    );
  }
}

。。。以上

猜你喜欢

转载自blog.csdn.net/Lee_taotao/article/details/82798601
今日推荐