基本用法

根据文档,安卓back键的处理主要就是一个事件监听:

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

starter-kit里,我们在App这一级别,实现了按back键回退导航栈的功能:

 class App extends React.Component {
componentWillMount() {
if (Platform.OS === 'android') {
BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
}
}
componentWillUnmount() {
if (Platform.OS === 'android') {
BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
}
}
onBackAndroid = () => {
const nav = this.navigator;
const routers = nav.getCurrentRoutes();
if (routers.length > 1) {
nav.pop();
return true;
}
return false;
};
……
}

注意这里为了方便后续removeEventListener,采用了用绑定this的函数属性的方法来创建回调函数,而非箭头函数或者bind(this),这一点参考之前的博文

代码中,当componentWillMount的时候挂接事件。对于应用根组件来说,这个生命周期就基本和我们应用的生命周期一致了。当back键被按下的时候,首先检查当前的导航栈,如果多余一个页面,则退回顶部的页面。

说明:BackAndroid在iOS平台下是一个空实现,所以理论上不做这个Platform.OS === 'android'判断也是安全的。

使用默认行为/退出应用

back键的默认行为就是退出应用了。我们通常需要判断某些条件,并最后决定是否要退出应用。上文中的例子就使用了第一种调用默认行为的方法:

如果所有事件监听函数中,没有任何一个返回真值,就会默认调用默认行为

如果你只挂接了一个监听函数,那么你的返回值就决定了是否要调用默认行为:true为不调用,false为调用

在上文代码中,我们如果导航栈多于一个页面,就不调用默认行为,而如果只有一个页面,则调用默认界面。

例子:“再按一次退出应用”

常有这种需求:按下back键以后,弹出一个toast,然后在一定时间内再按一次,才退出应用。这个代码就可以这样写:

  onBackAndroid = () => {
if (this.lastBackPressed && this.lastBackPressed + 2000 >= Date.now()) {
//最近2秒内按过back键,可以退出应用。
return false;
}
this.lastBackPressed = Date.now();
ToastAndroid.show('再按一次退出应用');
return true;
};

还有一种情况,我们在监听函数中不能决定是否要调用默认行为,要等待一个异步操作之后才调用默认行为,此时可以通过第二种办法:

使用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中文社区

react native 之 Android物理返回键的更多相关文章

  1. React Native 适配Android物理返回键,实现连续两次点击退出

    一直使用iPhone作为测试机开发,提交给测试同事Android版本后发现很多适配问题,其中一个非常明显的是,弹出一个modal后,点击Android的返回键,modal不会消失,直接navigati ...

  2. RN—Android 物理返回键监听

    A → B 使用 navigator 导航,用 goBack() 返回的时候传递参数 在 A 页面 this.props.navigation.navigate("B", { ca ...

  3. React Native组件之BackAndroid !安卓手机的物理返回键的使用

    ok!在安卓手机上,当我们用物理返回键的时候,会以一次性的将程序退出来,这样是很不好的体验,所以就需要使用RN的物理返回键组件:BackAndroid,其原理也就是 分析路由,然后pop()这样! o ...

  4. React Native For Android 架构初探

    版权声明:本文由王少鸣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/171 来源:腾云阁 https://www.qclo ...

  5. JavaScript监听手机物理返回键的两种解决方法

    JavaScript没有监听物理返回键的API,所以只能使用 popstate 事件监听. 有两个解决办法: 1.返回到指定的页面 pushHistory(); window.addEventList ...

  6. vue里监听安卓的物理返回键

    Hybrid App中,原生内嵌H5单页,由于安卓是有物理返回键的,按安卓物理返回键的时候会返回到上一个路由. 实际中需求是:当有弹层的时候,按物理返回键是关闭弹层,是页面的时候才执行返回上一个路由, ...

  7. Android Activity返回键控制的两种方式

    Android Activity返回键监听的两种方式 1.覆写Activity的OnBackPressed方法 官方解释: Called when the activity has detected ...

  8. android双击返回键退出程序

    今天给大家简单说一下,android双击返回键退出程序. @Override public boolean onKeyDown(int keyCode, KeyEvent event) {      ...

  9. js history对象 手机物理返回键

    有兴趣的可以了解下history对象,不感兴趣也可以直接跳到手机物理返回键监听部分 使用场景: 场景1:项目中一个表单页面,需得填写验证码,填写验证码后提交,由于使用的form直接提交,没有使用AJA ...

随机推荐

  1. 第 4 章 用 HTML5 建立超链接

    HTML 文件中最重要的应用之一就是超链接.—— 当鼠标单击一些文字.图片或其他网页元素时,浏览器会根据其指示载入一个新的页面或跳转到页面的其他位置. 超链接除了可链接文本外,也可链接各种媒体,如声音 ...

  2. URL加载jar

    // !/test.xml 是表示jar中的test.xml文件 final URL jarUrl = new URL("jar:file:/C:/proj/parser/jar/parse ...

  3. [转]使用CMS垃圾收集器产生的问题和解决方案

    在之前的一篇文章<CMS vs. Parallel GC>里通过实验的方式对比了并行和并发GC的优缺点,在文章结尾提到,CMS并行GC是大多数应用的最佳选择,然而, CMS并不是完美的,在 ...

  4. 0.5px的宽度的边框

    方法1:  .border {    position: relative;} .border:before {    content: "";/* 注意这里为双引号 */     ...

  5. Oracle 如何将“26-9月 -17 06.46.00.000000000 下午”字符串转换成标准日期格式

    今天,在读取日期格式数据时,出现这样的格式“26-9月 -17 06.46.00.000000000 下午”,在网上找了一下, 这个也是oracle的一种日期保存格式,数据都是日期类型,只是显示的结果 ...

  6. 003-RHEL7-Linux系统维护管理命令使用

    系统维护管理命令: date  查看日期,设置日期 只有超级用户才能用date命令设置时间 date  --help  显示时间的帮助命令 date{选项} 显示时间格式(以+开头,后面接时间格式) ...

  7. day26-python操作redis二

    字符串的操作 #redis中的string 在内存中都是按照一个key对应一个valus来存储的 import redis pool = redis.ConnectionPool(host=" ...

  8. 使用laravel搭建CURD后台页面

    配置即一切 一切皆于需求,后台从0开始搭建,但是写了一两个页面后发现太多的是对单表的增删改查操作,于是就想到了,能不能做一个快速搭建的后台.想到一句话,配置即一切.如果一个CURD后台能只进行配置就自 ...

  9. oo作业总结报告2

    第五次作业 多线程电梯 多线程同步和控制的设计策略 明确类和对象,以及是否区分对象实例.具体类可以从类图中看出: 明确线程的类型和数量.输入作为一个线程,调度作为一个线程,三个电梯独立工作,互不影响, ...

  10. [整理]Kadane算法

    仅能操作一次时,需每次观察是否有为负情况置零.多次操作时,仅需判断是否后者大于前者. leetcode 53.121.122 [代码] class Solution { public int maxS ...