React Native

React Native常用第三方框架之导航react-navi

2017-12-13  本文已影响0人  代码森林中的一只猫

前面我们学习了React Native常见的组件的属性和方法,以及简单的应用,那我们接下来学习一下常用的第三方的组件,第一个就是navigation和TabBar。

一.导入

npm install react-navigation --save

二.简介

react-navigation主要包括导航,底部tab,顶部tab,侧滑等,功能很强大,而且体验接近原生。今天我们介绍的组件分别为:

(一).StackNavigator

基础用法/属性介绍

const MyApp = StackNavigator({ 
// 对应界面名称 
MyTab: { screen: MyTab, }, 
Detail: { screen: Detail, navigationOptions:{ headerTitle:'详情', headerBackTitle:null, } }, 
},
{ headerMode: 'screen', });

导航配置

Demo

组件注册


const Navigator = StackNavigator(
 {  Login: {screen: Login}, 
    ForgotPassword: {screen: ForgotPassword, navigationOptions: {header: null,}}, 
    CodeLogin: {screen: CodeLogin}, }, { navigationOptions: { headerStyle: {backgroundColor: color.theme}, headerBackTitle: null, headerTintColor: '#ffffff', showIcon: true, }, 
    transitionConfig: TransitionConfiguration,
    headerMode: 'screen', // 导航栏的显示模式, screen: 有渐变透明效果, float: 无透明效果, none: 隐藏导航栏 }
);

动画切换

const TransitionConfiguration = () => ({
 screenInterpolator: (sceneProps) => { const {scene} = sceneProps;
 const {route} = scene; const params = route.params || {}; 
 const transition = params.transition || 'forHorizontal';
 return CardStackStyleInterpolator[transition](sceneProps); },
 });

Model弹出

const {navigate} = this.props.navigation; 
navigate('CodeLogin', {transition: 'forVertical'});

参数传递

const {navigate} = this.props.navigation;
navigate('CodeLogin', {phone: this.state.phone});

读取参数


phone=this.props.navigation.state.params.phone,

函数传递


navigate('CodeLogin', { setPictureData: this.setPictureData.bind(this) });

函数调用

this.props.navigation.state.params.setPictureData(data.path)

重置路由切换导航控制器

this.props.navigation.dispatch(resetAction)})

切换到Main页面

const resetAction = NavigationActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Main'}) ] })

关于goBack返回指定页面

react-navigation是提供了goBack()到指定页面的方法的,那就是在goBack()中添加一个参数,但当你使用goBack('Main')的时候,你会发现并没有跳转,原因是react-navigation默认goBack()中的参数是系统随机分配的key,而不是手动设置的routeName,而方法内部又没有提供可以获得key的方法,所以这里只能通过修改源码将key换成routeName了。
下面的内容直接引用了hello老文的内容

把项目/node_modules/react-navigation/src/routers/StackRouter.js文件里的
const backRoute = state.routes.find((route: *) => route.key === action.key);
改成 const backRoute = state.routes.find(route => route.routeName === action.key);

但不是很完美, 这里的component要填想返回的组件的前一个组件的routeName, 比如你的栈里顺序是home1, home2, home3, home4, 在home4里要返回home2, 使用this.props.navigation.goBack('home3'); 并且又会带出一个问题: goBack()方法没反应了, 必须加个null进去, 写成goBack(null)...
关于goBack返回指定页面的修改完善版

if (action.type === NavigationActions.BACK) {
    let backRouteIndex = null;
    if (action.key) {

      const backRoute = state.routes.find(
        /* $FlowFixMe */
        /* 修改源码 */
        route => route.routeName === action.key
        /* (route: *) => route.key === action.key */
      );
      /* $FlowFixMe */
      console.log('backRoute =====',backRoute);
      backRouteIndex = state.routes.indexOf(backRoute);
      console.log('backRoute =====',backRouteIndex);
    }
    if (backRouteIndex == null) {
      return StateUtils.pop(state);
    }
    if (backRouteIndex >= 0) {
      return {
        ...state,
        routes: state.routes.slice(0, backRouteIndex+1),
        index: backRouteIndex - 1 + 1,
      };
    }
  }

关于快速点击会导致多次跳转的问题解决办法

修改react-navigation目录下,scr文件夹中的addNavigationHelpers.js文件,可以直接替换成下面的文本

export default function<S: *>(navigation: NavigationProp<S, NavigationAction>) {
  // 添加点击判断
  let debounce = true;
  return {
      ...navigation,
      goBack: (key?: ?string): boolean =>
          navigation.dispatch(
              NavigationActions.back({
                  key: key === undefined ? navigation.state.key : key,
              }),
          ),
      navigate: (routeName: string,
                 params?: NavigationParams,
                 action?: NavigationAction,): boolean => {
          if (debounce) {
              debounce = false;
              navigation.dispatch(
                  NavigationActions.navigate({
                      routeName,
                      params,
                      action,
                  }),
              );
              setTimeout(
                  () => {
                      debounce = true;
                  },
              500,
              );
              return true;
          }
          return false;
      },
    /**
     * For updating current route params. For example the nav bar title and
     * buttons are based on the route params.
     * This means `setParams` can be used to update nav bar for example.
     */
    setParams: (params: NavigationParams): boolean =>
      navigation.dispatch(
        NavigationActions.setParams({
          params,
          key: navigation.state.key,
        }),
      ),
  };
}

安卓上,使用TextInput的时候会让TabBar顶起来的解决办法

最简单的解决办法就是在android目录中,添加一句话

目录:android/app/src/main/AndroidManifest.xml中,添加

android:windowSoftInputMode="stateAlwaysHidden|adjustPan|adjustResize"
上一篇下一篇

猜你喜欢

热点阅读