React Navigation 3x系列教程』之createStackNavigator開發(fā)指南

createStackNavigator

createStackNavigator提供APP屏幕之間切換的能力俱诸,它是以棧的形式還管理屏幕之間的切換,新切換到的屏幕會(huì)放在棧的頂部旷偿。

屏幕轉(zhuǎn)場風(fēng)格

默認(rèn)情況下,createStackNavigator提供了轉(zhuǎn)場過渡效果壁酬,在Android和iOS上過渡效果是不同的邓嘹,這也是React Native重平臺(tái)性的一個(gè)體現(xiàn),在Android上從屏幕底部淡入擅笔,在iOS上是從屏幕的右側(cè)劃入志衣,當(dāng)然你也可以通過配置讓StackNavigator支持屏幕從底部滑入的效果。

createStackNavigator API

createStackNavigator(RouteConfigs, StackNavigatorConfig):

  • RouteConfigs(必選):路由配置對(duì)象是從路由名稱到路由配置的映射猛们,告訴導(dǎo)航器該路由呈現(xiàn)什么念脯。
  • StackNavigatorConfig(可選):配置導(dǎo)航器的路由(如:默認(rèn)首屏,navigationOptions弯淘,paths等)樣式(如绿店,轉(zhuǎn)場模式mode、頭部模式等)耳胎。

從createStackNavigator API上可以看出createStackNavigator支持通過RouteConfigsStackNavigatorConfig兩個(gè)參數(shù)來創(chuàng)建createStackNavigator導(dǎo)航器惯吕。

提示:和本文配套的還有一個(gè)React Navigation3x的視頻教程,歡迎學(xué)習(xí)怕午。

RouteConfigs

RouteConfigs支持三個(gè)參數(shù)screen废登、path以及navigationOptions

  • screen(必選):指定一個(gè) React 組件作為屏幕的主要顯示內(nèi)容郁惜,當(dāng)這個(gè)組件被createStackNavigator加載時(shí)堡距,它會(huì)被分配一個(gè)navigation prop。
  • path(可選):用來設(shè)置支持schema跳轉(zhuǎn)時(shí)使用兆蕉,具體使用會(huì)在下文的有關(guān)Schema章節(jié)中講到羽戒;
  • navigationOptions(可選):用以配置全局的屏幕導(dǎo)航選項(xiàng)如:title、headerRight虎韵、headerLeft等易稠;

StackNavigatorConfig

react-navigation源碼中可以看出StackNavigatorConfig支持配置的參數(shù)有10個(gè)。

function createStackNavigator(routeConfigMap, stackConfig = {}) {
  const {
    initialRouteKey,
    initialRouteName,
    initialRouteParams,
    paths,
    navigationOptions,
    disableKeyboardHandling,
    getCustomActionCreators
  } = stackConfig;
  ...

這7個(gè)參數(shù)可以根據(jù)作用不同分為路由配置包蓝、視圖樣式配置兩類驶社,首先看用于路由配置的參數(shù):

用于路由配置的參數(shù):

  • initialRouteName: 設(shè)置默認(rèn)的頁面組件企量,必須是上面已注冊(cè)的頁面組件。
  • initialRouteParams: 初始路由的參數(shù)亡电。
  • navigationOptions: 屏幕導(dǎo)航的默認(rèn)選項(xiàng)届巩,下文會(huì)詳細(xì)講解。
  • initialRouteKey - 初始路由的可選標(biāo)識(shí)符份乒。
  • paths: 用來設(shè)置支持schema跳轉(zhuǎn)時(shí)使用恕汇,具體使用會(huì)在下文的有關(guān)Schema章節(jié)中講到。

提示:和本文配套的還有一個(gè)React Navigation3x的視頻教程或辖,歡迎學(xué)習(xí)瘾英。

用于導(dǎo)航樣式配置的參數(shù):

  • mode: 頁面切換模式: 左右是card(相當(dāng)于iOS中的push效果), 上下是modal(相當(dāng)于iOS中的modal效果)
    • card: 普通app常用的左右切換。
    • modal: 上下切換孝凌。
  • headerMode: 導(dǎo)航欄的顯示模式: screen: 有漸變透明效果, float: 無透明效果, none: 隱藏導(dǎo)航欄方咆。
    • float: 無透明效果, 默認(rèn)。
    • screen: 有漸變透明效果, 如微信QQ的一樣蟀架。
    • none: 隱藏導(dǎo)航欄瓣赂。
  • headerBackTitleVisible : 提供合理的默認(rèn)值以確定后退按鈕標(biāo)題是否可見,但如果要覆蓋它片拍,則可以使用true或` false 在此選項(xiàng)中煌集。
    • fade-in-place: 標(biāo)題組件交叉淡入淡出而不移動(dòng),類似于iOS的Twitter捌省,Instagram和Facebook應(yīng)用程序苫纤。 這是默認(rèn)值。
    • uikit: iOS的默認(rèn)行為的近似值纲缓。
      headerTransitionPreset: 指定在啟用headerMode:float時(shí)header應(yīng)如何從一個(gè)屏幕轉(zhuǎn)換到另一個(gè)屏幕卷拘。
  • cardStyle: 樣式(iOS上頁面切換會(huì)有白色漸變蒙層,想去掉則可以這樣設(shè)置祝高,cardStyle: { opacity: null },切換頁面時(shí)的頁面邊框也在這里可以設(shè)置)栗弟。
  • onTransitionStart: 頁面切換開始時(shí)的回調(diào)函數(shù) (我們可以在這里注冊(cè)一些通知,告知我們切面切換的狀態(tài)工闺,方便后面處理頁面切換事件)乍赫。
  • onTransitionEnd: 頁面切換結(jié)束時(shí)的回調(diào)函數(shù)。

navigationOptions(屏幕導(dǎo)航選項(xiàng))

支持一下參數(shù):

  • title: 可以作為headerTitle的備選字段(當(dāng)沒設(shè)置headerTitle時(shí)會(huì)用該字段作為標(biāo)題)陆蟆,也可以作為TabNavigator的tabBarLabel以及DrawerNavigator的drawerLabel雷厂。
  • header: 自定義導(dǎo)航條,可以通過設(shè)置null來隱藏導(dǎo)航條叠殷;
  • headerTitle: 標(biāo)題改鲫;
  • headerTitleAllowFontScaling: 標(biāo)題是否允許縮放,默認(rèn)true;
  • headerBackTitle: 定義在iOS上當(dāng)前頁面進(jìn)入到下一頁面的回退標(biāo)題钩杰,可以通過設(shè)置null來禁用它纫塌;
  • headerTruncatedBackTitle: 當(dāng)回退標(biāo)題不能顯示的時(shí)候顯示此屬性的標(biāo)題,比如回退標(biāo)題太長了讲弄;
  • headerBackImage:React 元素或組件在標(biāo)題的后退按鈕中顯示自定義圖片。 當(dāng)組件被調(diào)用時(shí)依痊,它會(huì)在渲染時(shí)收到許多 props 如:(tintColor避除,title)。 默認(rèn)為帶有 react-navigation/views/assets/back-icon.png 這張圖片的組件胸嘁,后者是平臺(tái)的默認(rèn)后圖標(biāo)圖像(iOS上為向左的符號(hào)瓶摆,Android上為箭頭)。
  • headerRight: 定義導(dǎo)航欄右邊視圖性宏;
  • headerLeft: 定義導(dǎo)航欄左邊視圖群井;
  • headerStyle: 定義導(dǎo)航欄的樣式,比如背景色等毫胜;
  • headerTitleStyle: 定義標(biāo)題的樣式书斜;
  • headerLeftContainerStyle:自定義 headerLeft 組件容器的樣式,例如酵使,增加 padding荐吉。
  • headerRightContainerStyle:自定義 headerRight 組件容器的樣式,,例如口渔,增加 padding样屠。
  • headerTitleContainerStyle:自定義 headerTitle 組件容器的樣式, 例如,增加 padding缺脉。
  • headerBackTitleStyle: 定義返回標(biāo)題的樣式痪欲;
  • headerPressColorAndroid:顏色為材料波紋 (Android >= 5.0);
  • headerTintColor: 定義導(dǎo)航條的tintColor攻礼,會(huì)覆蓋headerTitleStyle中的顏色业踢;
  • headerTransparent:默認(rèn)為 false。如果 true, 則標(biāo)頭將不會(huì)有背景, 除非您顯式提供 headerStyle 或 headerBackground秘蛔。
  • headerBackground:與headerTransparent一起使用陨亡,以提供在標(biāo)題后臺(tái)呈現(xiàn)的組件。 例如深员,您可以使用模糊視圖來創(chuàng)建半透明標(biāo)題负蠕。
  • gesturesEnabled: 定義是否能側(cè)滑返回,iOS默認(rèn)true倦畅,Android默認(rèn)false遮糖;
  • gestureResponseDistance: 定義滑動(dòng)返回的有效距離,水平狀態(tài)下默認(rèn):25叠赐,垂直狀態(tài)默認(rèn)135欲账;
  • gestureDirection: 設(shè)置關(guān)閉手勢的方向屡江。默認(rèn)從左向右,可以設(shè)置從右到左的滑動(dòng)操作赛不。

【案例】使用StackNavigator做界面導(dǎo)航惩嘉、配置navigationOptions

StackNavigator

第一步:創(chuàng)建一個(gè)StackNavigator類型的導(dǎo)航器

export const AppStackNavigator = createStackNavigator({
    HomePage: {
        screen: HomePage
    },
    Page1: {
        screen: Page1,
        navigationOptions: ({navigation}) => ({
            title: `${navigation.state.params.name}頁面名`//動(dòng)態(tài)設(shè)置navigationOptions
        })
    },
    Page2: {
        screen: Page2,
        navigationOptions: {//在這里定義每個(gè)頁面的導(dǎo)航屬性,靜態(tài)配置
            title: "This is Page2.",
        }
    },
    Page3: {
        screen: Page3,
        navigationOptions: (props) => {//在這里定義每個(gè)頁面的導(dǎo)航屬性踢故,動(dòng)態(tài)配置
            const {navigation} = props;
            const {state, setParams} = navigation;
            const {params} = state;
            return {
                title: params.title ? params.title : 'This is Page3',
                headerRight: (
                    <Button
                        title={params.mode === 'edit' ? '保存' : '編輯'}
                        onPress={() =>
                            setParams({mode: params.mode === 'edit' ? '' : 'edit'})}
                    />
                ),
            }
        }
    },
}, {
    defaultNavigationOptions: {
        // header: null,// 可以通過將header設(shè)為null 來禁用StackNavigator的Navigation Bar
    }
});

提示:和本文配套的還有一個(gè)React Navigation3x的視頻教程文黎,歡迎學(xué)習(xí)。

第二步:配置navigationOptions:

步驟一的代碼中通過兩種方式配值了navigationOptions:

靜態(tài)配置:

對(duì)Page2的navigationOptions配置是通過靜態(tài)配置完成的:

Page2: {
    screen: Page2,
    navigationOptions: {//在這里定義每個(gè)頁面的導(dǎo)航屬性殿较,靜態(tài)配置
        title: "This is Page2.",
    }
},

這種方式被稱為靜態(tài)配置耸峭,因?yàn)閚avigationOptions中的參數(shù)是直接Hard Code的不依賴于變量。

動(dòng)態(tài)配置:

對(duì)Page3的navigationOptions配置是通過動(dòng)態(tài)配置完成的:

Page3: {
    screen: Page3,
    navigationOptions: (props) => {//在這里定義每個(gè)頁面的導(dǎo)航屬性淋纲,動(dòng)態(tài)配置
        const {navigation} = props;
        const {state, setParams} = navigation;
        const {params} = state;
        return {
            title: params.title ? params.title : 'This is Page3',
            headerRight: (
                <Button
                    title={params.mode === 'edit' ? '保存' : '編輯'}
                    onPress={() =>
                        setParams({mode: params.mode === 'edit' ? '' : 'edit'})}
                />
            ),
        }
    }
},

從上述代碼中可以看出Page3的navigationOptions依賴于props這個(gè)變量所以是動(dòng)態(tài)的劳闹,當(dāng)props中的內(nèi)容發(fā)生變化時(shí),navigationOptions也會(huì)跟著變化洽瞬;

提示:除了在創(chuàng)建createStackNavigator時(shí)配置navigationOptions外本涕,在StackNavigator之外也可以配置navigationOptions;

createStackNavigator之外也可以配置navigationOptions

方式一:

Page2.navigationOptions = {
     title: "This is Page2.",
};

方式二:

export default class Page1 extends React.Component {
    //也可在這里定義每個(gè)頁面的導(dǎo)航屬性片任,這里的定義會(huì)覆蓋掉別處的定義
    static navigationOptions = {
        title: 'Page1',
    };
    ...

提示:和本文配套的還有一個(gè)React Navigation3x的視頻教程偏友,歡迎學(xué)習(xí)。

第三步:界面跳轉(zhuǎn)

export default class HomePage extends React.Component {
    //在這里定義每個(gè)頁面的導(dǎo)航屬性
    static navigationOptions = {
        title: 'Home',
        headerBackTitle:'返回哈哈',//設(shè)置返回此頁面的返回按鈕文案对供,有長度限制
    }

    render() {
        const {navigation} = this.props;
        return <View style={{flex: 1, backgroundColor: "orange",}}>
            <Text style={styles.text}>歡迎來到HomePage</Text>
            <Button
                title="Go To Page1"
                onPress={() => {
                    navigation.navigate('Page1', {name: '動(dòng)態(tài)的'});
                }}
            />
            <Button
                title="Go To Page2"
                onPress={() => {
                    navigation.navigate('Page2');
                }}
            />
            <Button
                title="Go To Page3"
                onPress={() => {
                    navigation.navigate('Page3',{ name: 'Devio' });
                }}
            />
        </View>
    }
}

代碼解析:

頁面跳轉(zhuǎn)可分為兩步:

    1. 獲取navigation:
    const {navigation} = this.props;
    
    1. 通過navigate(routeName, params, action)進(jìn)行頁面跳轉(zhuǎn):
     navigation.navigate('Page2');
     navigation.navigate('Page3',{ name: 'Devio' });
    

    這里在跳轉(zhuǎn)到Page3的時(shí)候傳遞了參數(shù){ name: 'Devio' }位他;

提示:和本文配套的還有一個(gè)React Navigation3x的視頻教程,歡迎學(xué)習(xí)产场。

第四步:更新頁面Params與返回

export default class Page3 extends React.Component {
    render() {
        const {navigation} = this.props;
        const {state, setParams} = navigation;
        const {params} = state;
        const showText = params.mode === 'edit' ? '正在編輯' : '編輯完成';
        return <View style={{flex: 1, backgroundColor: "gray",}}>
            <Text style={styles.text}>歡迎來到Page3</Text>
            <Text style={styles.showText}>{showText}</Text>
            <TextInput
                style={styles.input}
                onChangeText={text=>{
                    setParams({title:text})
                }}
            />
            <Button
                title="Go Back"
                onPress={() => {
                    navigation.goBack();
                }}
            />
        </View>
    }
}

代碼解析:

在上述代碼中通過:

 <TextInput
    style={styles.input}
    onChangeText={text=>{
        setParams({title:text})
    }}
/>

將輸入框中內(nèi)容的變化鹅髓,通過setParams({title:text})更新到頁面的標(biāo)題上,你會(huì)看到當(dāng)輸入框中內(nèi)容發(fā)生變化時(shí)京景,標(biāo)題也會(huì)跟著變窿冯。

當(dāng)用戶單擊Go Back按鈕時(shí),通過:

navigation.goBack();

實(shí)現(xiàn)了返回上一頁确徙;

類似上述的應(yīng)用場景有很多醒串,大家可以通過與本教程配套的最新版React Native+Redux打造高質(zhì)量上線App視頻教程進(jìn)行進(jìn)一步學(xué)習(xí)react-navigation的更多高級(jí)應(yīng)用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缠沈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌洲愤,老刑警劉巖颓芭,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柬赐,居然都是意外死亡亡问,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門肛宋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玛界,“玉大人,你說我怎么就攤上這事悼吱。” “怎么了良狈?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵后添,是天一觀的道長。 經(jīng)常有香客問我薪丁,道長遇西,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任严嗜,我火速辦了婚禮粱檀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘漫玄。我一直安慰自己茄蚯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布睦优。 她就那樣靜靜地躺著渗常,像睡著了一般。 火紅的嫁衣襯著肌膚如雪汗盘。 梳的紋絲不亂的頭發(fā)上皱碘,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音隐孽,去河邊找鬼癌椿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛菱阵,可吹牛的內(nèi)容都是我干的踢俄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼送粱,長吁一口氣:“原來是場噩夢啊……” “哼褪贵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤脆丁,失蹤者是張志新(化名)和其女友劉穎世舰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體槽卫,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡跟压,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歼培。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片震蒋。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖躲庄,靈堂內(nèi)的尸體忽然破棺而出查剖,到底是詐尸還是另有隱情,我是刑警寧澤噪窘,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布笋庄,位于F島的核電站,受9級(jí)特大地震影響倔监,放射性物質(zhì)發(fā)生泄漏直砂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一浩习、第九天 我趴在偏房一處隱蔽的房頂上張望静暂。 院中可真熱鬧,春花似錦谱秽、人聲如沸洽蛀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辱士。三九已至,卻和暖如春听绳,著一層夾襖步出監(jiān)牢的瞬間颂碘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工椅挣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留头岔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓鼠证,卻偏偏與公主長得像峡竣,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子量九,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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