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

因項目升級到0.47.1,之前的navigator不能再使用,so再次研究了react-navigation的使用,先推薦下寫的不錯的文章~

  1. ReactNative導(dǎo)航新寵兒react-navigation
  2. React Native——react-navigation的使用
  3. React Native未來導(dǎo)航者:react-navigation 使用詳解
  4. react-navigation使用
  5. React-navigation之StackNavigator
  6. redux與react-navigation的集成
  7. React Navigation官方文檔
(一)StackNavigator參數(shù)詳解
const AppNavigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

下面來詳細介紹下兩個參數(shù):

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
        }
    }
};

上面用到了一個參數(shù)navigationOptions,他是用來配置頁面的標題參數(shù)。我們可以在路由里面配置參數(shù),像上面的示例一樣;你也可以在頁面中配置,需要在頁面中定義一個靜態(tài)常量navigationOptions。

navigationOptions

參數(shù)說明:
title: 這個即可以作為頭部標題,也可以作為返回標題和Tab標題
header: 自定義導(dǎo)航條,系統(tǒng)的導(dǎo)航條會隱藏
headerTitle: 標題
headerBackTitle: 回退標題
headerTruncatedBackTitle: 當回退標題不能顯示的時候顯示此屬性的標題,比如回退標題太長了
headerRight: 定義導(dǎo)航欄右邊視圖
headerLeft: 定義導(dǎo)航欄左邊視圖
headerStyle: 定義導(dǎo)航欄的樣式,比如背景色等
headerTitleStyle: 定義標題的樣式
headerBackTitleStyle: 定義返回標題的樣式
headerTintColor: 定義導(dǎo)航條的tintColor,會覆蓋headerTitleStyle中的顏色
gesturesEnabled: 定義是否能側(cè)滑返回,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

這個參數(shù)主要是配置整個路由的,包括跳轉(zhuǎn)動畫,跳轉(zhuǎn)方式等。

參數(shù)說明:

initialRouteName: 初始化哪個界面為根界面,如果不配置,默認使用RouteConfigs中的第一個頁面當做根界面
initialRouteParams: 初始化根界面參數(shù),主要是給根視圖傳遞一些參數(shù),通過this.props.navigation.state.params可以取到
navigationOptions: 配置默認的navigationOptions
paths: 官方意思是覆蓋已經(jīng)配置的路由,但我沒試
mode: 跳轉(zhuǎn)方式,一種是card,默認的,在iOS上是從右到左跳轉(zhuǎn),在Android上是從下到上,都是使用原生系統(tǒng)的默認跳轉(zhuǎn)方式。一種是modal,只針對iOS平臺,模態(tài)跳轉(zhuǎn)。
headerMode: 跳轉(zhuǎn)過程中,導(dǎo)航條的動畫效果,有三個值,float表示會漸變,類似于iOS的原生效果,screen表示沒有漸變。none表示隱藏導(dǎo)航條
cardStyle: 可以統(tǒng)一定義界面的顏色,例如背景色
transitionConfig:配置頁面跳轉(zhuǎn)的動畫,是一個方法
onTransitionStart: 頁面跳轉(zhuǎn)動畫即將開始的回調(diào)方法
onTransitionEnd: 頁面跳轉(zhuǎn)動畫結(jié)束的回調(diào)方法

示例:

const StackNavigatorConfigs = {
    initialRouteName: 'Splash', // 初始化哪個界面為根界面
    initialRouteParams:{
        data:'你好Navigation'
    },
     navigationOptions:{
        headerTintColor:'blue'
    },
    mode:'card', // 跳轉(zhuǎn)方式:默認的card,在iOS上是從右到左跳轉(zhuǎn),在Android上是從下到上,都是使用原生系統(tǒng)的默認跳轉(zhuǎn)方式。
    headerMode:'screen', // 導(dǎo)航條動畫效果:float表示會漸變,類似于iOS的原生效果,screen表示沒有漸變。none表示隱藏導(dǎo)航條
    cardStyle:({
        backgroundColor:'#FFF'
    }),
    onTransitionStart:((route)=>{
        console.log('開始動畫');
    }),
    onTransitionEnd:((route)=>{
        console.log('結(jié)束動畫');
    }),
    transitionConfig:(()=>({
        //因為ios 的導(dǎo)航動畫默認是從左到右,所以,這里配置一下動畫,使用react-navigation已經(jīng)實現(xiàn)的從左到右的動畫,
        //適配Android,不過,需要導(dǎo)入動畫 
        //import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
        screenInterpolator:CardStackStyleInterpolator.forHorizontal,
    }))
};

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

(二)Navigation Prop

屬性說明:
navigate:路由方法,主要來啟動另一個頁面
state:狀態(tài),通過state能拿到很多參數(shù)。
setParams: 設(shè)置參數(shù),記住,一定不要在render方法中調(diào)用此方法。
goBack: 返回
dispatch: 給當前界面設(shè)置action,會替換原來的跳轉(zhuǎn),回退等事件

如圖所示,是打印的Navigation屬性:

QQ20170821-133654@2x.png
navigate

此方法可以傳三個參數(shù):navigate(routeName, params, action)
routeName: 頁面名稱,一定要在路由配置中配置。
params: 傳遞參數(shù)到下一個頁面
action: action

  1. 跳轉(zhuǎn)界面示例:
 this.props.navigation.navigate('Registered');
  1. 傳參跳轉(zhuǎn)示例:
 this.props.navigation.navigate('LoginSms', {
    loginPhone: this.state.phoneNumber
 });

另一界面接收該值:

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

通過state,我們能拿到傳遞過來的參數(shù),如上方獲取loginPhone示例。

goBack

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

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

設(shè)置當前頁面的參數(shù),記住,調(diào)用此方法一定要在componentDidMount

示例:

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

所有的Navigation Actions都會返回一個對象,這個對象可以使用navigation.dispatch方法傳遞到router。
下面的actions是可以使用的:

  • Navigate-導(dǎo)航到其他的route
  • Reset-使用新的state代替目前的state
  • Back-返回上一個state
  • Set Params-給定的route設(shè)置參數(shù)
  • Init-如果state沒有定義,用來初始化第一個state
action詳解
1.Navigate

Navigatie action會使用Navigate action的結(jié)果來更新當前的state。

  • routeName,字符串,必選項,在app的router里注冊的導(dǎo)航目的地的routeName。
  • params,對象,可選項,融合進目的地route的參數(shù)。
  • 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的結(jié)果來代替。

  • index,數(shù)組,必選,navigation state中route數(shù)組中激活route的index。
  • actions,數(shù)組,必選項,Navigation Actions數(shù)組,將會替代navigation state。
import { NavigationActions } from 'react-navigation'

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

index參數(shù)被用來定制化當前激活的route。舉個栗子:使用兩個routes Login和Main給一個基礎(chǔ)的stack navigation設(shè)置。為了重置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并且關(guān)閉當前screen.backaction creator接受一個可選的參數(shù):

  • key:字符串或者空,可選項,如果設(shè)定了,navigation將會從設(shè)定的key返回;如果是null,navigation將返回到任何地方。
import { NavigationActions } from 'react-navigation'

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

當dispatching setParams的時候,router將會產(chǎn)出一個新的state,這個state是已經(jīng)改變了特定route的參數(shù),以key作為身份驗證。

  • params:對象,必選參數(shù),融合進已經(jīng)存在的route參數(shù)中的新參數(shù)。
  • key:字符串,必選參數(shù),Route的key,應(yīng)該分配給新的參數(shù)。
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建立聯(lián)系,從而可以使用goBack和navigate等方法進行界面回退、跳轉(zhuǎn)等操作。
我們在自定義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-------'發(fā)現(xiàn),navigator傳值時一定要傳const navigator = this.props.navigation;而不能傳const {navigate} = this.props.navigation;后者只是傳了navigation屬性中的navigate方法,而非整個navigation,我們獲取不到goBack()方法,導(dǎo)致報錯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容