React NativeReact NativeReact Native学习

react-native新导航组件react-navigatio

2017-04-12  本文已影响33044人  hello老文

react-navigation

react-navigation 是今年1月份新出的一款react-native导航组件, 才几个月github就三千多star, 半官方身份, fb推荐使用, 据称性能和效果跟原生差不多. 可能是react-native导航组件的未来主流. 但现在还是beta版本(最新v1.0.0-beta.7) 坑还比较多, 文档和参考资料较少. 正式项目使用还需慎重.

有问题找 issues, 基本上坑都在这里.

官方文档

主要构成

按使用形式主要分三部分:

1 StackNavigator: 类似于普通的Navigator,屏幕上方导航栏
2 TabNavigator: 相当于iOS里面的TabBarController,屏幕下方的标签栏
3 DrawerNavigator: 抽屉效果,侧边滑出

StackNavigator 导航栏

API: StackNavigator(RouteConfigs, StackNavigatorConfig)

// 注册导航
const Navs = StackNavigator({
    Home: { screen: Tabs },
    HomeTwo: {
        screen: HomeTwo,  // 必须, 其他都是非必须
        path:'app/homeTwo', 使用url导航时用到, 如 web app 和 Deep Linking
        navigationOptions: {}  // 此处设置了, 会覆盖组件内的`static navigationOptions`设置. 具体参数详见下文
    },
    HomeThree: { screen: HomeThree },
    HomeFour: { screen: HomeFour }
}, {
    initialRouteName: 'Home', // 默认显示界面
    navigationOptions: {  // 屏幕导航的默认选项, 也可以在组件内用 static navigationOptions 设置(会覆盖此处的设置)
        header: {  // 导航栏相关设置项
            backTitle: '返回',  // 左上角返回键文字
            style: {
                backgroundColor: '#fff'
            },
            titleStyle: {
                color: 'green'
            }
        },
        cardStack: {
            gesturesEnabled: true
        }
    }, 
    mode: 'card',  // 页面切换模式, 左右是card(相当于iOS中的push效果), 上下是modal(相当于iOS中的modal效果)
    headerMode: 'screen', // 导航栏的显示模式, screen: 有渐变透明效果, float: 无透明效果, none: 隐藏导航栏
    onTransitionStart: ()=>{ console.log('导航栏切换开始'); },  // 回调
    onTransitionEnd: ()=>{ console.log('导航栏切换结束'); }  // 回调
});

navigationOptions

参数:

在组件中设置static navigationOptions示例:

static navigationOptions = {
    title: 'homeThree',
    header: (navigation, defaultHeader) => ({
      ...defaultHeader,  // 默认预设
      visible: true  // 覆盖预设中的此项
    }),
    cardStack: {
        gesturesEnabled: false  // 是否可以右滑返回
    }
};

// 或这样
static navigationOptions = {
    // title: 'Two', // 写死标题
    title: (navigation, childRouter) => {  // 动态标题
        if (navigation.state.params.isSelected) {
            return `${navigation.state.params.name}选中`;
        } else {
            return `${navigation.state.params.name}没选中`;
        }
    },
    header: ({ state, setParams, goBack }) => {
        let right;
        if (state.params.isSelected) {
            right = (<Button title="取消" onPress={() => setParams({ isSelected: false })}/>);
        } else {
            right = (<Button title="选择" onPress={() => setParams({ isSelected: true })}/>);
        }
        let left = (<Button title="返回" onPress={() => goBack()}/>);
        let visible = false;  // 是否显示导航栏
        return { right, left, visible };
    },
    // header: {left: <Button title="返回"/>},
};

StackNavigatorConfig

参数:

TabNavigator 标签栏

// 注册tabs
const Tabs = TabNavigator({
    Home: {
        screen: Home,
        navigationOptions: {  // 也可以写在组件的static navigationOptions内
            tabBar: {
                label: '首页',
                icon: ({tintColor}) => (<Image source={require('./app/images/home.png')} style={[{tintColor: tintColor},styles.icon]}/>),
            },
        }
    },
    Bill: {
        screen: Bill,
        navigationOptions: {
            tabBar: {
                label: '账单',
               icon: ({tintColor}) => (<Image source={require('./app/images/bill.png')} style={[{tintColor: tintColor},styles.icon]}/>),
            },
        }
    },
    Me: {
        screen: Me,
        navigationOptions: {
            tabBar: {
                label: '我',
                icon: ({tintColor}) => (<Image source={require('./app/images/me.png')} style={[{tintColor: tintColor},styles.icon]}/>),
            },
        }
    }
  }, {
      animationEnabled: false, // 切换页面时是否有动画效果
      tabBarPosition: 'bottom', // 显示在底端,android 默认是显示在页面顶端的
      swipeEnabled: false, // 是否可以左右滑动切换tab
      backBehavior: 'none', // 按 back 键是否跳转到第一个Tab(首页), none 为不跳转
      tabBarOptions: {
          activeTintColor: '#ff8500', // 文字和图片选中颜色
          inactiveTintColor: '#999', // 文字和图片未选中颜色
          showIcon: true, // android 默认不显示 icon, 需要设置为 true 才会显示
          indicatorStyle: {
              height: 0  // 如TabBar下面显示有一条线,可以设高度为0后隐藏
          }, 
          style: {
              backgroundColor: '#fff', // TabBar 背景色
              // height: 44
          },
          labelStyle: {
              fontSize: 10, // 文字大小
          },
      },
});

DrawerNavigator抽屉

const DrawerNav = DrawerNavigator({
    Home: { screen: Home },
    Bill: { screen: Bill },
    Me: { screen: Me },
    HomeTwo: { screen: HomeTwo },
    HomeThree: { screen: HomeThree },
    HomeFour: { screen: HomeFour },
    BillTwo: { screen: BillTwo },
    BillThree: { screen: BillThree }
}, {
    drawerWidth: 200, // 抽屉宽
    drawerPosition: 'left', // 抽屉在左边还是右边
    // contentComponent: CustomDrawerContentComponent,  // 自定义抽屉组件
    contentOptions: {
      initialRouteName: Home, // 默认页面组件
      activeTintColor: 'white',  // 选中文字颜色
      activeBackgroundColor: '#ff8500', // 选中背景颜色
      inactiveTintColor: '#666',  // 未选中文字颜色
      inactiveBackgroundColor: '#fff', // 未选中背景颜色
      style: {  // 样式
        
      }
    }
});

navigation

StackNavigator中注册后的组件都有navigation这个属性. navigation又有5个参数:navigate, goBack, state, setParams, dispatch, 可以在组件下console.log一下this.props就能看到.

Navigation Actions

Deep Link

其他app或浏览器使用url打开次app并进入指定页面. 如浏览器输入url demo4://home/home3直接进入home3页面.

iOS版设置

  1. 使用Xcode设置Schemes;
  2. AppDelegate添加一下代码:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  return [RCTLinkingManager application:application openURL:url
                      sourceApplication:sourceApplication annotation:annotation];
}
  1. js组件在注册路由时设置唯一的路径path, 例如Home2: { screen: Home2, path:'app/Home2' };
  2. 在手机浏览器访问demo4://app/Home2, 弹窗选择打开, 就可以打开demo4 app并进到Home2页面了.
上一篇下一篇

猜你喜欢

热点阅读