使用react-navigation詳解(四)--功能優(yōu)化

一冬阳、實(shí)現(xiàn)Android返回鍵點(diǎn)擊兩次退出應(yīng)用

從網(wǎng)上找到一段代碼喊衫,如下:

componentWillMount(){  
    BackHandler.addEventListener('hardwareBackPress', this._onBackAndroid );  
}  
  
  
componentUnWillMount(){  
    BackHandler.addEventListener('hardwareBackPress', this._onBackAndroid);  
}  
  
_onBackAndroid=()=>{  
    let now = new Date().getTime();  
    if(now - lastBackPressed < 2500) {  
        return false;  
    }  
    lastBackPressed = now;  
    ToastAndroid.show('再點(diǎn)擊一次退出應(yīng)用',ToastAndroid.SHORT);  
    return true;  
}  

經(jīng)測(cè)試發(fā)現(xiàn)這段代碼并不是十分正確,因?yàn)椴徽撛谀膫€(gè)界面埠胖,我們點(diǎn)擊返回鍵都會(huì)提示“再點(diǎn)擊一次退出應(yīng)用”糠溜,而我們想要的效果是如果界面不是根界面淳玩,點(diǎn)擊返回按鈕,返回上一頁(yè)非竿;如果是根界面蜕着,點(diǎn)擊提示“再點(diǎn)擊一次退出應(yīng)用”,再次點(diǎn)擊退出應(yīng)用红柱。
那怎么判斷它是不是根界面呢承匣?又在哪里判斷呢?
我們發(fā)現(xiàn)在onBackAndroid方法中是不能通過(guò)this.props.navigation拿到navigation的锤悄,但是在navigation中有一個(gè)onNavigationStateChange方法韧骗,可以得到導(dǎo)航狀態(tài)的改變,打印log如下:

WX20170823-140433@2x.png

其中:prevNav是之前導(dǎo)航狀態(tài)零聚,nav是當(dāng)前導(dǎo)航狀態(tài)袍暴,action是當(dāng)前進(jìn)行的操作。所以我們可以通過(guò)當(dāng)前導(dǎo)航的狀態(tài)中的routes來(lái)判斷當(dāng)前界面是否為根界面隶症,代碼如下:

/**
 * Created by sybil052 on 2017/8/18.
 */
...
let routes = [];
let lastBackPressed = null;
...
    componentDidMount() {
        BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
    }


    componentWillUnmount() {
        BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
        lastBackPressed = null;
    }

    onBackAndroid() {
        if (routes.length === 1) { // 根界面
            if (lastBackPressed && lastBackPressed + 2000 >= Date.now()) {
                return false;
            }
            lastBackPressed = Date.now();
            Toast.showShortCenter('再點(diǎn)擊一次退出應(yīng)用');
            return true;
        }
    }
    render() {
        return (
            <AppNavigator
                onNavigationStateChange={(prevNav, nav, action) => {
                console.log('prevNav=',prevNav);
                console.log('nav=',nav);
                console.log('action=',action);
                routes = nav.routes;
            }}/>
        );
    }

還有一種方法可以在onBackAndroid()方法中拿到navigation政模,即在頂層組件上調(diào)用導(dǎo)航,在同一級(jí)別的Navigation screen之間使用Navigator蚂会,可以使用react的ref選項(xiàng):

/**
 * Created by sybil052 on 2017/8/28.
 */
...
let lastBackPressed = null;
...
    componentDidMount() {
        BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
    }

    componentWillUnmount() {
        BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
        lastBackPressed = null;
    }

    onBackAndroid() {
        if(this.navigator._navigation.state.routes.length > 1) {
            this.navigator._navigation.goBack();
            return true;
        }
        if (lastBackPressed && lastBackPressed + 2000 >= Date.now()) {
            return false;
        }
        lastBackPressed = Date.now();
        Toast.showShortCenter('再點(diǎn)擊一次退出應(yīng)用');
        return true;
    }
    render() {
        return (
            <AppNavigator
                ref={nav => { this.navigator = nav; }}
            }}/>
        );
    }

注:這個(gè)解決辦法只能用在頂層navigator上~

這樣淋样,就實(shí)現(xiàn)了我們想要的效果~

二、快速點(diǎn)擊多次跳轉(zhuǎn)界面問(wèn)題

當(dāng)我們快速點(diǎn)擊跳轉(zhuǎn)時(shí)胁住,會(huì)開(kāi)啟多個(gè)重復(fù)的界面趁猴,如何解決呢?

解決這個(gè)問(wèn)題需要修改react-navigation源碼彪见,詳細(xì)見(jiàn)問(wèn)題Prevent navigating twice when tapping too fast儡司,找到scr文件夾中的addNavigationHelpers.js文件,替換為如下文本即可:

export default function<S: *>(navigation: NavigationProp<S, NavigationAction>) {  
  // 添加點(diǎn)擊判斷  
  let debounce = true;  
  return {  
      ...navigation,  
      goBack: (key?: ?string): boolean =>  
          navigation.dispatch(  
              NavigationActions.back({  
                  key: key === undefined ? navigation.state.key : key,  
              }),  
          ),  
      navigate: (routeName: string,  
                 params?: NavigationParams,  
                 action?: NavigationAction,): boolean => {  
          if (debounce) {  
              debounce = false;  
              navigation.dispatch(  
                  NavigationActions.navigate({  
                      routeName,  
                      params,  
                      action,  
                  }),  
              );  
              setTimeout(  
                  () => {  
                      debounce = true;  
                  },  
              500,  
              );  
              return true;  
          }  
          return false;  
      },  
    /** 
     * For updating current route params. For example the nav bar title and 
     * buttons are based on the route params. 
     * This means `setParams` can be used to update nav bar for example. 
     */  
    setParams: (params: NavigationParams): boolean =>  
      navigation.dispatch(  
        NavigationActions.setParams({  
          params,  
          key: navigation.state.key,  
        }),  
      ),  
  };  
}  
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末企巢,一起剝皮案震驚了整個(gè)濱河市枫慷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖或听,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件探孝,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡誉裆,警方通過(guò)查閱死者的電腦和手機(jī)顿颅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)足丢,“玉大人粱腻,你說(shuō)我怎么就攤上這事≌兜” “怎么了绍些?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)耀鸦。 經(jīng)常有香客問(wèn)我柬批,道長(zhǎng),這世上最難降的妖魔是什么袖订? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任氮帐,我火速辦了婚禮,結(jié)果婚禮上洛姑,老公的妹妹穿的比我還像新娘上沐。我一直安慰自己,他們只是感情好楞艾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布参咙。 她就那樣靜靜地躺著,像睡著了一般产徊。 火紅的嫁衣襯著肌膚如雪昂勒。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天舟铜,我揣著相機(jī)與錄音戈盈,去河邊找鬼。 笑死谆刨,一個(gè)胖子當(dāng)著我的面吹牛塘娶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痊夭,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼刁岸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了她我?” 一聲冷哼從身側(cè)響起虹曙,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤迫横,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后酝碳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體矾踱,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年疏哗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了呛讲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡返奉,死狀恐怖贝搁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情芽偏,我是刑警寧澤雷逆,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站哮针,受9級(jí)特大地震影響关面,放射性物質(zhì)發(fā)生泄漏坦袍。R本人自食惡果不足惜十厢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捂齐。 院中可真熱鬧蛮放,春花似錦、人聲如沸奠宜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)压真。三九已至娩嚼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間滴肿,已是汗流浹背岳悟。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泼差,地道東北人贵少。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像堆缘,于是被迫代替她去往敵國(guó)和親滔灶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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