[React Native]導(dǎo)航器Navigator

官方提供了兩種導(dǎo)航器:NavigatorNavigatorIOS渐苏,后者只能在iOS平臺(tái)使用掀潮,而前者是可以兼容Android和iOS平臺(tái)的,詳細(xì)介紹請參考官方介紹琼富。

基本使用方式:

  • initialRoute:初始化路由仪吧,指定第一個(gè)頁面
  • configureScene:配置頁面切換場景
  • renderScene:渲染場景,返回需要顯示的頁面

常見的一個(gè)寫法:

// ...
import FirstPage from './FirstPage';
class Demo10 extends Component {
  render() {
    return (
        <Navigator
            style={{flex: 1}}
            initialRoute= {{id: 'FirstPage', component: FirstPage}}
            configureScene= {this.configureScene}
            renderScene= {this.renderScene}
        />
    );
  }
  configureScene(route, routeStack) {
    if (route.sceneConfig) { // 有設(shè)置場景
        return route.sceneConfig;
    }
    return Navigator.SceneConfigs.PushFromRight; // 默認(rèn)鞠眉,右側(cè)彈出
  }
  renderScene(route, navigator) {
    return <route.component {...route.passProps} navigator= {navigator}/>;
  }
}
// ...

initialRoute薯鼠、configureScene、renderScene三個(gè)方法都和一個(gè)重要的參數(shù)route有關(guān)聯(lián)械蹋。

route:表示路由對象的信息出皇,我們看下它包含哪些參數(shù)

export interface Route {
    component?: React.ComponentClass<ViewProperties> // 必要參數(shù),目標(biāo)頁面
    id?: string  // 通常用來設(shè)置一個(gè)與component匹配的標(biāo)識(shí)
    title?: string // 常用來設(shè)置component頁面的標(biāo)題參數(shù)
    passProps?: Object; // 用來傳遞參數(shù)

    //anything else
    [key: string]: any

    //Commonly found properties
    backButtonTitle?: string  // 標(biāo)題欄左邊按鈕文字
    content?: string
    message?: string;
    index?: number
    onRightButtonPress?: () => void // 標(biāo)題欄右邊按鈕點(diǎn)擊事件
    rightButtonTitle?: string // 標(biāo)題欄右邊按鈕文字
    sceneConfig?: SceneConfig // 切換場景的參數(shù)
    wrapperStyle?: any
}

本篇文章我們會(huì)使用到id哗戈、component郊艘、passProps、sceneConfig這四個(gè)參數(shù)谱醇,其他類似于backButtonTitle暇仲、onRightButtonPress等,這些參數(shù)在使用通用導(dǎo)航欄的時(shí)候會(huì)用到副渴。

實(shí)際項(xiàng)目中奈附,這種方式基本不會(huì)用,因?yàn)闃I(yè)務(wù)的復(fù)雜等原因會(huì)導(dǎo)致通用導(dǎo)航欄變得越來越臃腫煮剧,不可維護(hù)斥滤,如果想了解的同學(xué),可以參考這篇文章勉盅。

Navigator和其他平臺(tái)的導(dǎo)航一樣佑颇,也是使用“棧”的形式來維護(hù)頁面草娜。我們都知道“椞粜兀”是先進(jìn)后出的原則,Navigator多數(shù)API是“遵循”這個(gè)原則的宰闰。

不同的是茬贵,Navigator還提供了更加靈活的API簿透,使得我們可以從類似“棧頂”跳轉(zhuǎn)到“棧底”,同時(shí)還能保持“棧底”以上的頁面存在而不銷毀解藻,我覺得可以用“偽椑铣洌”來形容它。

常用API

  • push(route) - 跳轉(zhuǎn)到新的場景螟左,并且將場景入棧啡浊,你可以稍后跳轉(zhuǎn)過去
  • pop() - 跳轉(zhuǎn)回去并且卸載掉當(dāng)前場景
  • popToTop() - pop到棧中的第一個(gè)場景,卸載掉所有的其他場景胶背。
  • popToRoute(route) - pop到路由指定的場景巷嚣,在整個(gè)路由棧中,處于指定場景之后的場景將會(huì)被卸載奄妨。

  • jumpBack() - 跳回之前的路由涂籽,當(dāng)然前提是保留現(xiàn)在的,還可以再跳回來砸抛,會(huì)給你保留原樣评雌。
  • jumpForward() - 上一個(gè)方法不是調(diào)到之前的路由了么,用這個(gè)跳回來就好了直焙。
  • jumpTo(route) - 跳轉(zhuǎn)到已有的場景并且不卸載景东。
    備注:與push&popxxx效果類似,只是不會(huì)卸載場景

  • replace(route) - 用一個(gè)新的路由替換掉當(dāng)前場景
  • replaceAtIndex(route, index) - 替換掉指定序列的路由場景
  • replacePrevious(route) - 替換掉之前的場景
    備注:replacexxx:僅僅替換場景奔誓,并不會(huì)跳轉(zhuǎn)

  • resetTo(route) - 跳轉(zhuǎn)到新的場景斤吐,并且重置整個(gè)路由棧
  • immediatelyResetRouteStack(routeStack) - 用新的路由數(shù)組來重置路由棧
  • getCurrentRoutes() - 獲取當(dāng)前棧里的路由,也就是push進(jìn)來厨喂,沒有pop掉的那些和措。

為了演示以上API的使用,我們新建三個(gè)js文件蜕煌,FirstPage.js派阱、SecondPage.jsThirdPage.js

FirstPage作為導(dǎo)航控制器的根頁面斜纪,請參考文章開頭給出的代碼示例贫母。

push&popxxx:

1、FirstPage->push->SecondPage:傳遞參數(shù)from

// FirstPage.js
_push()
{
    this.props.navigator.push({
        id: 'SecondPage',
        component: SecondPage,
        passProps: {
            from: 'First Page'
        },
        sceneConfig: Navigator.SceneConfigs.HorizontalSwipeJump
    });
}

2盒刚、SecondPage->push->ThirdPage腺劣,代碼類似就不貼了。然后因块,ThirdPage->pop->SecondPage琳钉,返回上一個(gè)頁面

// ThirdPage.js
_pop()
{
    this.props.navigator.pop();
}

3翘地、ThirdPage->popToTop->FirstPage堡距,返回第一個(gè)頁面

// ThirdPage.js
_popToTop() {
    this.props.navigator.popToTop();
}

4、ThirdPage->popToRoute->FirstPage寨辩,返回第一個(gè)頁面

// ThirdPage.js
_popToRouteById(id) {
    var destRoute;
    this.props.navigator.getCurrentRoutes().map((route, i) => {
        if (route.id === id) {
            destRoute = route;
        }
    });
    // 攜帶參數(shù)
    destRoute.passProps = {from: 'Third Page'};
    this.props.navigator.popToRoute(destRoute);
}

效果圖如下:


push&popxxx.gif

jumpxxx:

1、SecondPage->jumpBack->FirstPage:返回上一個(gè)場景歼冰,并且不卸載當(dāng)前場景

// SecondPage.js
_jumpBack() {
    this.props.navigator.jumpBack();
}

2、FirstPage->jumpForward->SecondPage:與jumpBack配套使用耻警,返回觸發(fā)jumpBack的場景

// FirstPage.js
_jumpForward()
{
    this.props.navigator.jumpForward();
}

效果圖如下:

jumpxxx.gif

我們打印下FirstPageSecondPage的生命周期函數(shù)componentDidMountcomponentWillUnmount隔嫡。

// FirstPage.js
componentDidMount() {
    console.log("FirstPage: componentDidMount");
}

componentWillUnmount() {
    console.log("FirstPage: componentWillUnmount");
}

// SecondPage.js
componentDidMount() {
    console.log("SecondPage: componentDidMount");
}

componentWillUnmount() {
    console.log("SecondPage: componentWillUnmount");
}

lifecircle.png

我們看到,在來回的跳轉(zhuǎn)過程中SecondPage并沒有被卸載甘穿。

更有趣的是腮恩,從SecondPage jumpBack之后。在FirstPage頁面温兼,如果點(diǎn)擊push秸滴,你會(huì)發(fā)現(xiàn)舊的SecondPage會(huì)被卸載,然后會(huì)創(chuàng)建一個(gè)新的SecondPage募判。console如下:

lifecircle2.png

3荡含、SecondPage->jumpTo->FirstPage:跳轉(zhuǎn)到一個(gè)已存在的場景,并且不卸載當(dāng)前場景

// SecondPage.js
_jumpToById(id) {
    var destRoute;
    this.props.navigator.getCurrentRoutes().map((route, i) => {
        if (route.id === id) {
            destRoute = route;
        }
    });
    // 攜帶參數(shù)
    destRoute.passProps = {from: 'Second Page'};
    this.props.navigator.jumpTo(destRoute);
}

replacexxx:

新建一個(gè)場景FourthPage.js届垫。當(dāng)前“検鸵海”里面的場景為FirstPage->SecondPage->ThirdPage
1装处、ThirdPage ->replacePrevious:在ThirdPage頁面替換上一個(gè)場景(也就是SecondPage)為FourthPage误债。

// ThirdPage.js
_replacePrevious()
{
    this.props.navigator.replacePrevious({
        id: 'FourthPage',
        component: FourthPage,
    });
}

此時(shí),“椡ǎ”里面的場景為FirstPage->FourthPage->ThirdPage寝蹈。

2、replace(route)replaceAtIndex(route, index)replacePrevious非常類似登淘,只是替換的場景不同而已箫老,這里不做講解,大家自己測試一下就知道效果了形帮。

  • replace(route) - 用一個(gè)新的路由替換掉當(dāng)前場景
  • replaceAtIndex(route, index) - 替換掉指定序列的路由場景

需要注意的是槽惫,replacexxx:僅僅替換場景,并不會(huì)跳轉(zhuǎn)辩撑。

resetTo:

跳轉(zhuǎn)到新的場景界斜,并且重置整個(gè)路由棧。

想象這樣一個(gè)場景合冀,我們有個(gè)App各薇,用戶登錄之后,可能已經(jīng)進(jìn)入三級頁面,此時(shí)用戶希望切換用戶重新登錄峭判,這時(shí)候我們就需要跳轉(zhuǎn)到登錄頁面开缎,并且清空其他所有頁面。

此時(shí)林螃,就需要使用到resetTo奕删。

我們在ThirdPage->resetTo->FourthPage,然后在FourthPage使用pop疗认,看下是否還有其他頁面存在完残。

// ThirdPage.js
_resetTo()
{
    this.props.navigator.resetTo({
        id: 'FourthPage',
        component: FourthPage,
    });
}
// FourthPage.js
_pop()
{
    this.props.navigator.pop();
}

效果圖如下:

resetTo

我們看到整個(gè)路由“棧”被重新初始化横漏,FourthPage成為“椊魃瑁”的根頁面。

immediatelyResetRouteStack(routeStack):

用新的路由數(shù)組來重置路由棧缎浇,與resetTo類似扎拣,只不過resetTo參數(shù)為一個(gè)對象,而immediatelyResetRouteStack(routeStack)為一個(gè)數(shù)組素跺,感興趣的同學(xué)可以自己嘗試一下效果二蓝。

本文的源碼地址Demo10

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市亡笑,隨后出現(xiàn)的幾起案子侣夷,更是在濱河造成了極大的恐慌,老刑警劉巖仑乌,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件百拓,死亡現(xiàn)場離奇詭異,居然都是意外死亡晰甚,警方通過查閱死者的電腦和手機(jī)衙传,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厕九,“玉大人蓖捶,你說我怎么就攤上這事”庠叮” “怎么了俊鱼?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長畅买。 經(jīng)常有香客問我并闲,道長,這世上最難降的妖魔是什么谷羞? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任帝火,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘犀填。我一直安慰自己蠢壹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布九巡。 她就那樣靜靜地躺著图贸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪比庄。 梳的紋絲不亂的頭發(fā)上求妹,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音佳窑,去河邊找鬼。 笑死父能,一個(gè)胖子當(dāng)著我的面吹牛神凑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播何吝,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼溉委,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了爱榕?” 一聲冷哼從身側(cè)響起瓣喊,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎黔酥,沒想到半個(gè)月后藻三,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡跪者,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年棵帽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渣玲。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逗概,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忘衍,到底是詐尸還是另有隱情逾苫,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布枚钓,位于F島的核電站铅搓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏秘噪。R本人自食惡果不足惜狸吞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蹋偏,春花似錦便斥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至黎棠,卻和暖如春晋渺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脓斩。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工木西, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人随静。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓八千,卻偏偏與公主長得像,于是被迫代替她去往敵國和親燎猛。 傳聞我的和親對象是個(gè)殘疾皇子恋捆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

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