使用react-navigation详解(一)--StackNavigator

因项目升级到0.47.1,之前的navigator不能再使用,so再次研究了react-navigation的使用,先推荐下写的不错的文章~

  1. ReactNative导航新宠儿react-navigation
  2. React Native——react-navigation的使用
  3. React Native未来导航者:react-navigation 使用详解
  4. react-navigation使用
  5. React-navigation之StackNavigator
  6. redux与react-navigation的集成
  7. React Navigation官方文档
(一)StackNavigator参数详解
const AppNavigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

下面来详细介绍下两个参数:

RouteConfigs

它主要是来配置页面路由的,所有的界面都必须配置在里面。
示例:

const StackRouteConfigs = {
    Splash: {
        screen: Splash, // 界面
        navigationOptions: {
            header: null // 无标题栏
        }
    },
    Login: {
        screen: Login,
        navigationOptions: {
            header: null
        }
    },
    Main: {
        screen: TabBarNavigator,
        navigationOptions: {
            header: null
        }
    },
    Registered: {
        screen: Registered,
        navigationOptions: {
            header: null
        }
    },
    LoginSms: {
        screen: LoginSms,
        navigationOptions: {
            header: null
        }
    }
};

上面用到了一个参数navigationOptions,他是用来配置页面的标题参数。我们可以在路由里面配置参数,像上面的示例一样;你也可以在页面中配置,需要在页面中定义一个静态常量navigationOptions。

navigationOptions

参数说明:
title: 这个即可以作为头部标题,也可以作为返回标题和Tab标题
header: 自定义导航条,系统的导航条会隐藏
headerTitle: 标题
headerBackTitle: 回退标题
headerTruncatedBackTitle: 当回退标题不能显示的时候显示此属性的标题,比如回退标题太长了
headerRight: 定义导航栏右边视图
headerLeft: 定义导航栏左边视图
headerStyle: 定义导航栏的样式,比如背景色等
headerTitleStyle: 定义标题的样式
headerBackTitleStyle: 定义返回标题的样式
headerTintColor: 定义导航条的tintColor,会覆盖headerTitleStyle中的颜色
gesturesEnabled: 定义是否能侧滑返回,iOS默认true,Android默认false

具体页面中配置示例:

static navigationOptions=({
    title:'首页',
    header:(
        <View style={{width:Dimensions.get('window').width,height:64,backgroundColor:'#1B82D1'}}/>
    ),
    headerTitle:(
        <View style={{width:60,height:20,backgroundColor:'#F0F'}}/>
    ),
    headerBackTitle:'返回',
    headerTruncatedBackTitle:'回退',
    headerRight:(
        <View>
            <Text>right</Text>
        </View>
    ),
    headerLeft:(
        <View>
            <Text>left</Text>
        </View>
    ),
    headerStyle: {
        backgroundColor:'yellow'
    },
    headerTitleStyle:{
        color:'red'
    },
    headerBackTitleStyle:{
        tintColor:'#E8E8E8'
    },
    headerTintColor:'#F33',
    gesturesEnabled:false
});
StackNavigatorConfig

这个参数主要是配置整个路由的,包括跳转动画,跳转方式等。

参数说明:

initialRouteName: 初始化哪个界面为根界面,如果不配置,默认使用RouteConfigs中的第一个页面当做根界面
initialRouteParams: 初始化根界面参数,主要是给根视图传递一些参数,通过this.props.navigation.state.params可以取到
navigationOptions: 配置默认的navigationOptions
paths: 官方意思是覆盖已经配置的路由,但我没试
mode: 跳转方式,一种是card,默认的,在iOS上是从右到左跳转,在Android上是从下到上,都是使用原生系统的默认跳转方式。一种是modal,只针对iOS平台,模态跳转。
headerMode: 跳转过程中,导航条的动画效果,有三个值,float表示会渐变,类似于iOS的原生效果,screen表示没有渐变。none表示隐藏导航条
cardStyle: 可以统一定义界面的颜色,例如背景色
transitionConfig:配置页面跳转的动画,是一个方法
onTransitionStart: 页面跳转动画即将开始的回调方法
onTransitionEnd: 页面跳转动画结束的回调方法

示例:

const StackNavigatorConfigs = {
    initialRouteName: 'Splash', // 初始化哪个界面为根界面
    initialRouteParams:{
        data:'你好Navigation'
    },
     navigationOptions:{
        headerTintColor:'blue'
    },
    mode:'card', // 跳转方式:默认的card,在iOS上是从右到左跳转,在Android上是从下到上,都是使用原生系统的默认跳转方式。
    headerMode:'screen', // 导航条动画效果:float表示会渐变,类似于iOS的原生效果,screen表示没有渐变。none表示隐藏导航条
    cardStyle:({
        backgroundColor:'#FFF'
    }),
    onTransitionStart:((route)=>{
        console.log('开始动画');
    }),
    onTransitionEnd:((route)=>{
        console.log('结束动画');
    }),
    transitionConfig:(()=>({
        //因为ios 的导航动画默认是从左到右,所以,这里配置一下动画,使用react-navigation已经实现的从左到右的动画,
        //适配Android,不过,需要导入动画 
        //import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
        screenInterpolator:CardStackStyleInterpolator.forHorizontal,
    }))
};

注:
CardStackStyleInterpolator.forHorizontal // 从左到右
CardStackStyleInterpolator.forVertical // 从下到上
CardStackStyleInterpolator.forFadeFromBottomAndroid // 从底部淡出

(二)Navigation Prop

属性说明:
navigate:路由方法,主要来启动另一个页面
state:状态,通过state能拿到很多参数。
setParams: 设置参数,记住,一定不要在render方法中调用此方法。
goBack: 返回
dispatch: 给当前界面设置action,会替换原来的跳转,回退等事件

如图所示,是打印的Navigation属性:

QQ20170821-133654@2x.png
navigate

此方法可以传三个参数:navigate(routeName, params, action)
routeName: 页面名称,一定要在路由配置中配置。
params: 传递参数到下一个页面
action: action

  1. 跳转界面示例:
 this.props.navigation.navigate('Registered');
  1. 传参跳转示例:
 this.props.navigation.navigate('LoginSms', {
    loginPhone: this.state.phoneNumber
 });

另一界面接收该值:

constructor(props) {
    super(props);
    const loginPhone = this.props.navigation.state.params.loginPhone;
}
state

通过state,我们能拿到传递过来的参数,如上方获取loginPhone示例。

goBack

如果什么都不传,回退到上一个界面;传null,回退到任意界面;传key,可以回退到指定界面。
示例:

this.props.navigation.goBack(); // 回退到上一个界面
this.props.navigation.goBack(null); // 回退到任意界面
this.props.navigation.goBack('Login'); // 回退到指定界面
setParams

设置当前页面的参数,记住,调用此方法一定要在componentDidMount

示例:

componentDidMount() {
    var {setParams} = this.props.navigation;
    setParams({'loginPhone':'13800001111'});
}
dispatch

所有的Navigation Actions都会返回一个对象,这个对象可以使用navigation.dispatch方法传递到router。
下面的actions是可以使用的:

  • Navigate-导航到其他的route
  • Reset-使用新的state代替目前的state
  • Back-返回上一个state
  • Set Params-给定的route设置参数
  • Init-如果state没有定义,用来初始化第一个state
action详解
1.Navigate

Navigatie action会使用Navigate action的结果来更新当前的state。

  • routeName,字符串,必选项,在app的router里注册的导航目的地的routeName。
  • params,对象,可选项,融合进目的地route的参数。
  • actions,对象,可选项(高级),如果screen也是一个navigator,次级action可以在子router中运行。在文档中描述的任何actions都可以作为次级action。
import { NavigationActions } from 'react-navigation';

const navigateAction = NavigationActions.navigate({

    routeName: 'Splash',
    params: {},
    action: NavigationActions.navigate({ routeName: 'Login'})
});

this.props.navigation.dispatch(navigateAction);
2.Reset

Reset action删掉所有的navigation state并且使用几个actions的结果来代替。

  • index,数组,必选,navigation state中route数组中激活route的index。
  • actions,数组,必选项,Navigation Actions数组,将会替代navigation state。
import { NavigationActions } from 'react-navigation'

const resetAction = NavigationActions.reset({
    index: 0,
    actions: [
        NavigationActions.navigate({ routeName: 'Main'})
    ]
});
this.props.navigation.dispatch(resetAction);
index参数的使用

index参数被用来定制化当前激活的route。举个栗子:使用两个routes Login和Main给一个基础的stack navigation设置。为了重置route到Main,但是在堆栈中又存放在Login screen之上,你可以这么做:

import { NavigationActions } from 'react-navigation'

const resetAction = NavigationActions.reset({
    index: 1,
    actions: [
        NavigationActions.navigate({ routeName: 'Login'}),
        NavigationActions.navigate({ routeName: 'Main'})
    ]
});
this.props.navigation.dispatch(resetAction);
3.Back

返回到前一个screen并且关闭当前screen.backaction creator接受一个可选的参数:

  • key:字符串或者空,可选项,如果设定了,navigation将会从设定的key返回;如果是null,navigation将返回到任何地方。
import { NavigationActions } from 'react-navigation'

const backAction = NavigationActions.back({
    key: 'Home'
});
this.props.navigation.dispatch(backAction);
4.SetParams

当dispatching setParams的时候,router将会产出一个新的state,这个state是已经改变了特定route的参数,以key作为身份验证。

  • params:对象,必选参数,融合进已经存在的route参数中的新参数。
  • key:字符串,必选参数,Route的key,应该分配给新的参数。
import { NavigationActions } from 'react-navigation'
const setParamsAction = NavigationActions.setParams({
    params: { title: '首页' },
    key: 'id-1503398147429-3',
});
this.props.navigation.dispatch(setParamsAction);
(三)自定义NavigationBar

通过对上面的StackNavigator的了解,我们可以使用自定义的NavigationBar,也就是标题栏。
具体自定义NavigationBar的代码就不贴了,我们来说说怎样让自定义的标题栏和StackNavigator建立联系,从而可以使用goBack和navigate等方法进行界面回退、跳转等操作。
我们在自定义NavigationBar的时候,在render方法中会定义一个属性navigator,而我们在其他界面使用自定义的NavigationBar的时候会将这个属性传到NavigationBar中,这样我们就可以在自定义NavigationBar中使用goBack(),navigate等方法了。例如:
loginSms.js

    ...
    render() {
        const navigator = this.props.navigation;
        const {phoneNumber, smsCode} = this.state;
        return (
            <View
                style={stylesCommon.container}
            >
                <NavigationBar
                    title={'登录'}
                    navigator={navigator}
                />
                ...
            </View>
        );
    }
    ...

navigationBar.js

    render() {
        const {
            navigator,
            title,
            backIconClick,
            leftButtonConfig,
            style,
            ...
        } = this.props;
        let leftButtonConfig = this.props.leftButtonConfig;
        if (!leftButtonConfig) {
            leftButtonConfig = {
                type: 'image',
                image: backIcon,
                onClick: () => {
                    if (backIconClick) {
                        backIconClick();
                    } else {
                        if (navigator && !leftButtonHidden) {
                            console.log('--------navigator-------',navigator);
                            navigator.goBack();
                        }
                    }
                },
            };
        }
        return(
            ...
        );
    }
QQ20170821-133654@2x.png

注:通过打印'--------navigator-------'发现,navigator传值时一定要传const navigator = this.props.navigation;而不能传const {navigate} = this.props.navigation;后者只是传了navigation属性中的navigate方法,而非整个navigation,我们获取不到goBack()方法,导致报错。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容