根据文档,安卓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中文社区