Android onbackpressed实现返回键的拦截和弹窗流程分析
作者:知奕奕 时间:2021-09-11 09:07:22
前言
此文章主要解决拦截用户点击手机底部导航栏中的返回键时该事件的拦截;
此方法依然可以适用于fragment
onBackPressed()
这是 activity 中自带的拦截返回的方法;
每当我们按下底部导航的返回键时,就会调用该事件,我们可以通过重写它来阻止 activity 的销毁
譬如下方代码,我们直接把 super 注释掉,那么点击返回键时就不会有任何反应,因为我们并没有针对性的进行响应的事件处理
override fun onBackPressed() {
// super.onBackPressed()
}
onBackPressedDispatcher
fragment 没有提供 onBackPressed 方法,故大多数情况下使用 android 推荐的 onBackPressedDispatcher 来进行返回键的拦截操作;
接下来是一个拦截返回并弹窗,询问是否退出的一个小案例;
为便于大家理解,故直接使用 activity 而非 fragment;
首先使用属性委托 lazy,即懒加载的方式定义一个 onBackPressedDispatcher 变量
class NoteActivity : AppCompatActivity() {
private val dispatcher by lazy {
NoteActivity().onBackPressedDispatcher
}
override fun onCreate(savedInstanceState: Bundle?) {
...
}
}
接着在 oncreate
方法中注册 onBackPressedDispatcher
;
注册的方式即添加一个回调函数用处处理拦截时的动作,使用 addCallback
;
addCallback
有两个参数,第一个为上下文,第二个为 OnBackPressedCallback
函数方法(下面的代码使用了 lambda 的形式提高效率)
OnBackPressedCallback 函数接收一个参数,我们一般都填 true;
它还需要实现一个方法 handleOnBackPressed
,这里面就是处理对应实践的地方了
在 handleOnBackPressed 方法内:
如果想阻止返回事件,那就什么都不做
如果想允许返回事件,那就使用 finish,结束掉本 activity
override fun onCreate(savedInstanceState: Bundle?) {
...
dispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// 构造一个AlertDialog,具体怎么用不细说
AlertDialog.Builder(this@NoteActivity).apply {
setTitle("Oops!")
setMessage("请写上一个标题奥,不然咱没法保存")
setIcon(R.drawable.ic_info)
// 点击了确认按钮,直接使用finish销毁本activity
setPositiveButton("直接退出") { dialog, which ->
finish()
}
// 点了否定,就啥都不做,即不处理返回事件,那自然就不会销毁了
setNegativeButton("我再想想", null)
}.show()
}
}
)
}
最后,在 onBackPressed 中触发 onBackPressedDispatcher (因为返回键点击事件都由 onBackPressed 所拦截,onBackPressedDispatcher 仅仅是充当了一个助手的作用)
注意删掉或者注释原来的的 super,否则你点返回键就直接退出了,那就前功尽弃了!!!
override fun onBackPressed() {
dispatcher.onBackPressed()
}
全部代码展示:
package com.zhiyiyi.sqlitedemo
import android.content.DialogInterface
import android.database.sqlite.SQLiteDatabase
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.KeyEvent
import android.view.MotionEvent
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AlertDialog
import com.zhiyiyi.sqlitedemo.databinding.ActivityNoteBinding
import com.zhiyiyi.sqlitedemo.utils.DBHelper
class NoteActivity : AppCompatActivity() {
private lateinit var binding: ActivityNoteBinding
// 懒加载
private val dispatcher by lazy {
NoteActivity().onBackPressedDispatcher
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNoteBinding.inflate(layoutInflater)
setContentView(binding.root)
// 注册回调事件
dispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
AlertDialog.Builder(this@NoteActivity).apply {
setTitle("Oops!")
setMessage("请写上一个标题奥,不然咱没法保存")
setIcon(R.drawable.ic_info)
setPositiveButton("直接退出") { dialog, which ->
finish()
}
setNegativeButton("我再想想", null)
}.show()
}
}
)
}
// 检测返回键点击事件
override fun onBackPressed() {
dispatcher.onBackPressed()
}
}
来源:https://blog.csdn.net/delete_you/article/details/127822059
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
java实现zip,gzip,7z,zlib格式的压缩打包
浅谈java实现背包算法(0-1背包问题)
activemq整合springboot使用方法(个人微信小程序用)
教你怎么用Java获取国家法定节假日
深入多线程之:双向信号与竞赛的用法分析
java实现邮件发送
![](https://img.aspxhome.com/file/2023/2/68762_0s.jpg)
C#中泛型举例List<T>与DataTable相互转换
![](https://img.aspxhome.com/file/2023/1/71071_0s.jpg)
两种java实现二分查找的方式
![](https://img.aspxhome.com/file/2023/3/98123_0s.jpg)
Java 数据结构与算法系列精讲之环形链表
![](https://img.aspxhome.com/file/2023/2/81362_0s.gif)
Java中接口和抽象类的区别详解
Java详解Swing中的几种常用按钮的使用
![](https://img.aspxhome.com/file/2023/7/76197_0s.png)
Java 爬虫如何爬取需要登录的网站
![](https://img.aspxhome.com/file/2023/8/116218_0s.png)
springcloud项目占用内存好几个G导致服务器崩溃的问题
![](https://img.aspxhome.com/file/2023/6/61236_0s.png)
Java 实现RSA非对称加密算法
Java线程池submit阻塞获取结果的实现原理详解
![](https://img.aspxhome.com/file/2023/7/64797_0s.png)
Android 应用签名的两种方法
Java实现Http工具类的封装操作示例
详解Java的引用类型及使用场景
springboot 如何解决static调用service为null
Java中jstat命令的使用详解
![](https://img.aspxhome.com/file/2023/0/73090_0s.png)