Android开发经验谈Android开发Android知识

React Navigation制作导航栏

2017-10-21  本文已影响1599人  Evelynzzz

React Native开发有一点挺友好的,就是文档写的比较清楚详细,而且有中文网。中文网不只是把英语翻译成中文,而在需要注意的地方加了一些译注。最好不要忽略这些译注,不然新手很容易掉坑里,这也是我的亲身经验。

React Native现有几个导航组件,但是导航库react-navigation是社区主推使用的导航库。

如果你刚开始接触,那么直接选择React Navigation就好。如果你只针对iOS平台开发,并且想和系统原生外观一致,那么可以选择NavigatorIOS。

功能

首页>注册>登录>注销

这个Demo的主要页面如上所示。导航的逻辑:

  1. 进入首页,导航栏的右侧包含一个按钮,点击可以调用系统自带浏览器。

  2. a.选择注册,跳转到注册页面。
    b.如果已有账号,则点击登录跳转到登录页面。

  3. 注册成功自动跳转到登录页面。

  4. a.此时可以选择用刚注册的账户登录;
    b.或者点击导航栏的返回键回到首页。

  5. 登录成功自动跳转到包含两个标签页的页面。

  6. 选择“账户”,点击注销,可以直接跳转回首页。

导航栏流程图

整个过程不考虑cookie,着重考虑导航栏控制屏幕之间跳转。

实现


这个逻辑是很基础很简单的,用到了 React Navigation库的三个组件:

导航结构

能够跳转到的页面都要加到StackNavigator初始化中。

StackNavigator(RouteConfigs, StackNavigatorConfig)

第一个参数是Route配置,第二个参数是统一的导航栏样式等的配置。在Route配置中,可以单独配置某个页面的导航栏。比如Tabs页面,因为添加了底部标签页导航栏,不需要顶部的导航栏了,所以设置navigationOptionsheader,从而隐藏这个页面的顶部导航栏。

//App.js
//顶部导航栏
export const App = StackNavigator({
  Home: {screen: HomeScreen},           //首页
  Register: {screen: RegisterScreen},   //注册
  Login: {screen: LoginScreen},         //登录
  Tabs: {                         //登录之后的标签页
    screen: BottomTab,
    navigationOptions:{
      header: null  //隐藏顶部导航栏
    }
  },
},{
  navigationOptions: {    //配置顶部导航 
    headerTitleStyle: {   //导航栏文字的样式
        fontSize: 18,
        color: '#b2b2b2',
    },
    // headerBackTitleStyle: {    //‘返回’文字的样式
    //   color: '#b2b2b2'
    // },
    headerStyle: {        //导航栏的样式
        backgroundColor: '#343434',
        borderBottomColor: '#f5a623',
        borderBottomWidth: 1
    },
}
});

//注册组件。TestProject是APP的名称。
AppRegistry.registerComponent('TestProject', () => App);

跳转到某个页面

如果我们要跳转到StackNavigator中的某个页面,可以调用this.props.navigation提供的navigat方法。应用中的每个Screen组件都接收到一个navigation的prop。详情可阅读:
https://reactnavigation.org/docs/navigators/navigation-prop

const { navigate } = this.props.navigation;
navigate('Tabs',{username:this.state.username}) //可传递参数

首页>注册>登录>返回主页

注册成功之后自动跳转到登录页,这时候点击返回的,怎么直接返回主页,而不是返回上一级的注册页?

我的方法是,在注册成功之后,使用NavigationActionsreset方法重置导航的堆栈信息。只保留首页和当前的登录页。

//app.js
//注册之后自动跳转到登录页面中,并且重置导航stack,使得不能返回注册页面
export const afterRegisterAction = NavigationActions.reset({
  index: 1,   //1表示当前调度到Login页面
  actions: [  //新的导航操作历史
    NavigationActions.navigate({ routeName: 'Home'}),
    NavigationActions.navigate({ routeName: 'Login'}),
  ]
})

使用时:

import {afterRegisterAction} from '../App'
......
this.props.navigation.dispatch(afterRegisterAction)  //跳转到登录页面

在账户页面注销回到首页也是这个原理:

//回到首页,且清空stack中的其他的导航记录。
export const resetToHomeAction = NavigationActions.reset({
  index: 0,   //对应actions中的index。指定当前页面。
  actions: [  //替换之后的导航记录
    NavigationActions.navigate({ routeName: 'Home'})
  ]
})

底部标签页导航

使用TabNavigator制作标签页导航。清晰明了直接上代码:

import {Text} from 'react-native';
import { TabNavigator } from "react-navigation";
import AssetListScreen from './AssetList'
import AccountScreen from './Account'

const BottomTab = TabNavigator({
        AssetList: { screen: AssetListScreen},  //资产标签页
        Account: { screen: AccountScreen},      //账号标签页
    },
    {
        tabBarPosition: 'bottom',   //android默认的TabNavigator是在上方。在StackNavigator下面。所以需要特意指定。
        animationEnabled: true,     //标签切换时的动画
        tabBarOptions: {
            activeTintColor: '#f5a623', //active时标签中文字和Icon的颜色
            labelStyle: {   //标签文字的样式
                fontSize: 12
            },
            indicatorStyle:{   //android标签下划线的样式。注意这里不是设置color。
                backgroundColor: '#f5a623'
            },
            style: {    //整体标签栏的样式
                backgroundColor: '#343434',
            }, 
            showIcon: true,         //android上默认不显示icon。所以要特别设定。 
        }
    }
);

export default BottomTab;

导航栏中的按钮

在每个Screen组件的内部,可以设置navigationOptions来修改这一页的导航栏,比如设置标题等。

//Home.js
import Button from 'react-native-button' //使用react-native-button组件。其他按钮组件:https://js.coach/react-native

export default class HomeScreen extends React.Component {

    static navigationOptions = {
        title: 'ReactNativeDemo',
        headerRight: (  //定义导航栏右侧的按钮
            <Button 
            style={{fontSize:12, color:'#fff'}}
            containerStyle={{marginRight:10,height:30, width:50, overflow:'hidden', borderRadius:4, backgroundColor: '#343434', borderColor:'#b2b2b2', borderWidth:1, justifyContent:'center'}}
            onPress={()=>contact()} 
            >
                联系
            </Button>),
    };  
}
...

参考链接

上一篇下一篇

猜你喜欢

热点阅读