react native 之 Android物理返回鍵

基本用法

根據文檔,安卓back鍵的處理主要就是一個事件監聽:html

1 BackAndroid.addEventListener('hardwareBackPress', this.onBackPressed);
2 BackAndroid.removeEventListener('hardwareBackPress', this.onBackPressed);

starter-kit裏,咱們在App這一級別,實現了按back鍵回退導航棧的功能:react

 1 class App extends React.Component {
 2   componentWillMount() {
 3     if (Platform.OS === 'android') {
 4       BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
 5     }
 6   }
 7   componentWillUnmount() {
 8     if (Platform.OS === 'android') {
 9       BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
10     }
11   }
12   onBackAndroid = () => {
13     const nav = this.navigator;
14     const routers = nav.getCurrentRoutes();
15     if (routers.length > 1) {
16       nav.pop();
17       return true;
18     }
19     return false;
20   };
21   ……
22 }

注意這裏爲了方便後續removeEventListener,採用了用綁定this的函數屬性的方法來建立回調函數,而非箭頭函數或者bind(this),這一點參考以前的博文android

代碼中,當componentWillMount的時候掛接事件。對於應用根組件來講,這個生命週期就基本和咱們應用的生命週期一致了。當back鍵被按下的時候,首先檢查當前的導航棧,若是多餘一個頁面,則退回頂部的頁面。git

說明:BackAndroid在iOS平臺下是一個空實現,因此理論上不作這個Platform.OS === 'android'判斷也是安全的。

使用默認行爲/退出應用

back鍵的默認行爲就是退出應用了。咱們一般須要判斷某些條件,並最後決定是否要退出應用。上文中的例子就使用了第一種調用默認行爲的方法:github

若是全部事件監聽函數中,沒有任何一個返回真值,就會默認調用默認行爲

若是你只掛接了一個監聽函數,那麼你的返回值就決定了是否要調用默認行爲:true爲不調用,false爲調用react-native

在上文代碼中,咱們若是導航棧多於一個頁面,就不調用默認行爲,而若是隻有一個頁面,則調用默認界面。安全

例子:「再按一次退出應用」

常有這種需求:按下back鍵之後,彈出一個toast,而後在必定時間內再按一次,才退出應用。這個代碼就能夠這樣寫:異步

  onBackAndroid = () => {
    if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
      //最近2秒內按過back鍵,能夠退出應用。
      return false;
    }
    this.lastBackPressed = Date.now();
    ToastAndroid.show('再按一次退出應用');
    return true;
  };

還有一種狀況,咱們在監聽函數中不能決定是否要調用默認行爲,要等待一個異步操做以後才調用默認行爲,此時能夠經過第二種辦法:async

使用BACKANDROID.EXITAPP()來退出應用。

例子:在退出應用以前保存數據

寫法1:函數

  onBackAndroid = () =>{
    saveData().then(()=>{
      BackAndroid.exitApp();
    });
    return true;
  }

在監聽函數中,咱們開始異步事件,並直接return true。此時默認行爲不會被調用。當保存完畢後,咱們調用exitApp(),觸發默認行爲,退出應用。

寫法2:

  onBackAndroid = async () =>{
    await saveData();
    BackAndroid.exitApp();
  }

這裏咱們用了async函數,async 函數老是返回一個Promise,Promise做爲一個對象,也被認爲是一個「真值」,因此這種狀況下默認行爲老是不會被調用。當保存完畢後,咱們調用exitApp(),觸發默認行爲,退出應用。

根據當前界面決定做何動做

有時候咱們有這樣的需求:當用戶處於某些界面下時,back鍵要作特殊的動做,如:提示用戶是否要保存數據,或者解鎖界面禁止back鍵返回等等。此時,最佳實踐是在route或route中對應的Component上保存關於如何處理back鍵的信息:

 

onBackAndroid = () => {
    const nav = this.navigator;
    const routers = nav.getCurrentRoutes();
    if (routers.length > 1) {
      const top = routers[routers.length - 1];
      if (top.ignoreBack || top.component.ignoreBack){
        // 路由或組件上決定這個界面忽略back鍵
        return true;
      }
      const handleBack = top.handleBack || top.component.handleBack;
      if (handleBack) {
        // 路由或組件上決定這個界面自行處理back鍵
        return handleBack();
      }
      // 默認行爲: 退出當前界面。
      nav.pop();
      return true;
    }
    return false;
  };

原文轉載自:React Native中文社區

相關文章
相關標籤/搜索