美文网首页react-native
react-navigation相关bug的解决

react-navigation相关bug的解决

作者: 蚊小文 | 来源:发表于2018-03-15 12:03 被阅读368次

    让安卓实现push动画

    之前我群里的讨论怎么让安卓实现类似iOS的push动画,后来翻看官方issues的时候,真的发现了实现push动画的代码,在这里共享下

    // 先引入这个方法
    import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
    
    // 在StackNavigator配置headerMode的地方,使用transitionConfig添加
    {
        headerMode: 'screen',
        transitionConfig:()=>({
            screenInterpolator:CardStackStyleInterpolator.forHorizontal,
        })
    }
    

    修改页面的跳转动画

    如何将安卓的跳转动画改成iOS那样,react-navigation一共提供了4种跳转动画:
    1、从右向左: forHorizontal;
    2、从下向上: forVertical;
    3、安卓那种的从下向上: forFadeFromBottomAndroid;
    4、无动画: forInitial。

    但因为库的限制,想实现某些页面使用某种动画还是很难的,只能通过Demo中提供的笨方法来实现。

    首先还是导入react-navigation中的方法

    import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator';
    

    如果要改变跳转动画只能在StackNavigator中实现transitionConfig方法

    const MainStack = StackNavigator({
        Main:{
            screen:Main,
        },
    },{
        // mode:'modal',
        headerMode: 'screen',
        transitionConfig:()=>({
         // 只要修改最后的forVertical就可以实现不同的动画了。
          screenInterpolator:CardStackStyleInterpolator.forVertical,
        })
    });
    

    goBack返回指定页面

    react-navigation目录下src/routers/StackRouter.js

    iif (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,
          };
        }
      }
    

    注意:这样的修改源码之后,如果项目中使用Redux,并且启用了滑动返回,很会很大几率导致app卡死,所以并不太推荐这种方式,最好使用下面的方式

    关于快速点击重复跳转的解决办法

    如果想解决快速点击跳转的问题,需要修改部分源码。

    修改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"

    安卓返回键在react-navigation中的正常监听

    之前使用Navigator的时候,可以通过下面的方法实现监听安卓的返回键,但使用了react-navigation后,会很迷茫,不知该怎么监听了。

    Navigator的方法

    componentWillMount() {
        if (Platform.OS === 'android') {
          BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
        }
      }
    componentWillUnmount() {
        if (Platform.OS === 'android') {
          BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
        }
      }
    onBackAndroid = () => {
        const nav = this.navigator;
        const routers = nav.getCurrentRoutes();
        if (routers.length > 1) {
          nav.pop();
          return true;
        }
        return false;
      };
      ……
    }
    

    react-navigation的方式

    componentWillMount() {
        if (Platform.OS === 'android') {
            BackHandler.addEventListener('handwareBackPress',this.onBackAndroid)
        }
      }
    componentWillUnmount() {
        if (Platform.OS === 'android') {
            BackHandler.addEventListener('handwareBackPress',this.onBackAndroid)
        }
      }
    onBackAndroid = () => {
        const routers = nav.getCurrentRoutes();
        if (routers.length > 1) {
          return true;
        }
        return false;
      };
      ……
    }
    
    // 在跳转之后的页面中
    onBackAndroid = ()=> {
    
        const {routes} = this.props;
        console.log(routes);
        // alert(routes)
        if (routes.length > 1) {
            // 因为其他页面获得不到this.props,所以只能每个页面都写这个方法。
            this.props.navigation.goBack();
            return true;
        }
    }
    

    相关文章

      网友评论

        本文标题:react-navigation相关bug的解决

        本文链接:https://www.haomeiwen.com/subject/meenfftx.html