一、分析需求
-
需要监听安卓的返回键,点击安卓返回键的时候可以正常返回
-
但是当在tabs的几个页面中按返回键做如下的几个处理
-
如果在首页tab,那么在连续点击两次返回键后退出应用
-
在其他tab,按返回键不做处理
二、实现
1、思路
如果只是监听的话,那么所有页面都将会触发到同一个函数,所以要在处理函数中进行判断,如果是在首页中点击返回键,那么就再进行判断,
所以需要做的一步很重要的工作就是判断当前的页面是哪个页面。
笨笨的我刚开始想到的是在每个页面监听一次,然后各自拥有不同的处理函数,但是这个想法有一个很大的缺点就是,如果是在某个页面跳转到另一个页面的话,那么在b页面中按了返回键,a页面也会触发,这就相当于,我按了一次返回键,但是我退出了两个页面,这并不是我想要的结果。
然后我又想到了一个办法,就是利用mobx这个全局状态管理,去管理一个route这个状态,这个变量用来保存当前所在的页面的routename,
其他的页面想要处理,就在componentWillMount中对其进行操作,然后再componentWillUnmount的时候把这个route设定为它当前所在的顶级页面。
这个想法是正确的,但是我又遇到了一个问题,就是底部导航栏中,tab切换页面,这个要怎么办,虽然官方文档中有给出一个tabBarOnPress,但是这个参数有时候可以触发,有时候触发不了。即使修改了源代码,将我自定义的Onprss函数传给底层的组件,也没有办法(maybe是我写错了)。于是我找啊找啊,终于被我找到一个有用的组件(感谢StackOverflow!!!you saved my day!!!!)
这个组件就是NavigationEvents,它是棣属于react-navigation的,拥有几个参数
onWillFocus={payload => console.log('will focus')}//将要被点击
onDidFocus={payload => this.imagePicker() }//被点击
onWillBlur={payload => console.log('will blur', payload)}//将要离开
onDidBlur={payload => console.log('did blur', payload)}//离开
将这个组件放在几个tab对应的页面中,就实现了这个功能了(就是点击tab做对应的处理)
2、代码
App.js
componentWillMount() {
// //监听返回键
BackHandler.addEventListener('hardwareBackPress', this.onBackClicked);
}
componentWillUnmount() {
//取消对返回键的监听
BackHandler.removeEventListener('hardwareBackPress', this.onBackClicked);
}
//BACK物理按键监听
onBackClicked = () => {
console.log(store.dataFixStore.route)
const {route} = store.dataFixStore;
if (route != 'Home') {
return true;//true 表示返回上一页
}else {
if (this.lastBackPressed && this.lastBackPressed + 500 >= Date.now()) {
//最近0.5秒内按过back键,可以退出应用。
return false;
}
this.lastBackPressed = Date.now();
return true;
}
}
Home.js
return (
<View>
<NavigationEvents
onDidFocus={ ()=>{
this.props.dataFixStore.setRoute('Home')
}}
/>
</View>
)
其他几个tab对应的顶级页面也像上面这样,只要把setRoute中的参数改为对应的值就好。
在Home页面中的其他页面点击返回键作其他的处理,只要在componentWillMount将其设定为本页面,componentWillUnmout的时候设回Home即可
dataFixStore.js
import { observable, action } from "mobx";
import {
AsyncStorage,
}from 'react-native';
class DataFixStore {
//路由信息
@observable route = 'Home';
@action
setRoute = (route) => {
this.route = route
console.log(route)
};
}
const dataFixStore = new DataFixStore();
export { dataFixStore };
最后想说一句,bug不是罪过,菜才是!!!!