React Native StackNavigator Android 物理返回按钮处理(这里只做按两次退出应用的处理)
一、首先引入BackHandler
import { StackNavigator } from ‘react-navigation’;//引入StackNavigator
import { BackHandler,ToastAndroid ,View} from ‘react-native’;//由于这儿用到了Toast提示,便一起引入
首先列出项目入库文件App.js代码:
import {BackHandler, ToastAndroid ,View ,Platform} from 'react-native';
import {StackNavigator} from 'react-navigation';
import HomeScreen from './js/screen/HomeScreen';
import MineScreen from "./js/screen/MineScreen";
var stateIndex, oStateIndex = false, goBack = false;
var lastBackPressed;
var current = true;
type Props = {};
type State = {};
export default class App extends PureComponent<Props, State> {
componentWillUnmount() {//注册返回按钮事件监听
this.backHandler && this.backHandler.remove();
}
componentDidMount() {//移除返回按钮事件监听
this.backHandler = BackHandler.addEventListener('hardwareBackPress',
this.backOption);
}
backOption = () => {
if (current == true) {//如果是在首页
if (lastBackPressed && lastBackPressed + 2000 >= Date.now()) {
//最近2秒内按过back键,可以退出应用。
BackHandler.exitApp();
return false;
}
lastBackPressed = Date.now();
ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT);
return true;
} else {
if (this.props && this.props.navigation) {
this.props.navigator.pop();
}
}
}
render() {
return (
<View style={flex:1}
<Navigator
onNavigationStateChange={(prevState, newState, action) => {//注册路由改变监听事件
if (newState && newState.routes[newState.routes.length - 1].routeName == 'HomeScreen') {//如果当前路由是Home页面,则需要处理安卓物理返回按键。
current = true;
} else {
current = false;
}
}}
></Navigator>
</View>
);
}
}
const Navigator = StackNavigator(
{
HomeScreen: {screen: HomeScreen},
MineScreen: {screen: MineScreen},
},
{
initialRouteName: 'HomeScreen',
navigationOptions: {
header: null,
gesturesEnabled: Platform.OS == 'ios' ? true : false,
headerTintColor: '#333333',
headerBackTitle: null
},
}
)
二、自己根据需求编写Home.js和MineScreen.js文件,这里就不列出代码了。
附录:如果有的童鞋是用的Navigator导航,可以使用如下方式:
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
}
onBackAndroid = () => {
const nav = this.props.navigator;
const routers = nav.getCurrentRoutes();
if (routers.length > 1) {
nav.pop();
return true;
}else {
if (lastBackPressed && lastBackPressed + 2000 >= Date.now()) {
return false;
}
lastBackPressed = Date.now();
ToastAndroid.show('再按一次退出应用',1000);
return true;
}
};
留言:本篇博客主要记录自己在第一次处理安卓返回按钮监听和处理上的一些方式和技巧。
**附言:有的Android同鞋存在确实添加了BackHandler监听,在debug apk包下也能正常监听安卓手机的返回按钮,页面能够正常返回。
但是:在release包下按安卓物理返回键却会直接退出app。
针对这种情况,我还没找到更好的解决方法,这里只贴出我个人的处理办法:
第一步:创建一个全局的数据存储类。
DataObject.js
代码如下:
const object = {
//用来保存App.js所在类对象
APP:{},
};
export default object;
第二步:在App.js的构造方法中为DataObject类中的App变量赋值。
第三步:在/node_modules/react-native/Libraries/Utilities/BackHandler.android.js
文件中找到该处代码:
首先引入我们定义的DataObject类
import DataObject from '../../../../js/localData/DataObject'//引入我们定义的DataObject类
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function () {
let invokeDefault = true;
const subscriptions = Array.from(_backPressSubscriptions.values()).reverse();
for (let i = 0; i < subscriptions.length; ++i) {
if (subscriptions[i]()) {
invokeDefault = false;
break;
}
}
if (invokeDefault) {
//此处删除系统原有代码,添加如下代码
//TODO
if(DataObject.APP != undefined && DataObject.APP.backOption != undefined){//判断如果DataObject.APP未定义则不执行。
DataObject.APP.backOption()//调用APP.js中我们的backOption方法。
}
}
});
App.js类所有代码:
import DataObject from './js/localData/DataObject';
import {BackHandler, ToastAndroid ,View ,Platform} from 'react-native';
import {StackNavigator} from 'react-navigation';
import HomeScreen from './js/screen/HomeScreen';
import MineScreen from "./js/screen/MineScreen";
var stateIndex, oStateIndex = false, goBack = false;
var lastBackPressed;
var current = true;
type Props = {};
type State = {};
export default class App extends PureComponent<Props, State> {
//构造方法
constructor(props){
super(props)
DataObject.APP = this //为DataObject类中的App变量赋值
}
backOption = () => {
if (current == true) {//如果是在首页
if (lastBackPressed && lastBackPressed + 2000 >= Date.now()) {
//最近2秒内按过back键,可以退出应用。
BackHandler.exitApp();
return false;
}
lastBackPressed = Date.now();
ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT);
return true;
} else {
if (this.props && this.props.navigation) {
this.props.navigator.pop();
}
}
}
render() {
return (
<View style={flex:1}
<Navigator
onNavigationStateChange={(prevState, newState, action) => {//注册路由改变监听事件
if (newState && newState.routes[newState.routes.length - 1].routeName == 'HomeScreen') {//如果当前路由是Home页面,则需要处理安卓物理返回按键。
current = true;
} else {
current = false;
}
}}
></Navigator>
</View>
);
}
const Navigator = StackNavigator(
{
HomeScreen: {screen: HomeScreen},
MineScreen: {screen: MineScreen},
},
{
initialRouteName: 'HomeScreen',
navigationOptions: {
header: null,
gesturesEnabled: Platform.OS == 'ios' ? true : false,
headerTintColor: '#333333',
headerBackTitle: null
},
}
)
**