We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
其实最早接触到返回到概念是浏览器的 这小小的“后退”箭头按钮就是。 和他卧龙凤雏凑一堆的是“前进” 其实可以理解为对浏览记录的快捷跳转 如图所示 对于安卓的世界来说,返回堆栈就有Task 和 Activity的“宏观级别” 以及Framgment的“微观级别” 但是从用户体验角度上来讲,后退是“一致”的 另外现在安卓的发展也在往单Activity,多Framgment方向发展。 这个和Web前端的单页面方向很接近,殊途同归吧
虽然堆栈后退是常规操作。但是仍然有需要干预的可能和需要
操作体验的需要 比如第一个启动页面,如果按退出,整个app就“关”掉了。很多时候只是用户手滑(shou jian)了。 很多app,会提供一个提示,比如再按一次退出才真正退出。
业务方面考虑强需求 如果有的页面从业务角度讲就是必须不能后退的,必须完成后才能返回,比如登陆页,我首页又不允许匿名登陆的情况下。
确实需要自定义后退 比如当前的页面是一个内嵌了一个web浏览器,我点击后退。 “真实”的需求是我web后退一个页面,但是我把web页面直接给干掉了估计用户会很愤怒
优点 简单粗暴,直接在Activity里面Override就行了,几乎没有其他啥操作
缺点 局限在Activity的逻辑中,如果需要Framgment参与就必须写额外的接口和通信,对于飞速发展的Framgment来说显然落后了。
例子
@Override public void onBackPressed() { Logger.i("---onBackPressed---"); super.onBackPressed(); }
注意:这里super.onBackPressed();一定要调用,除非你想把后退功能给“裁剪”掉
2023-05-23 22:24:21.889 21439-21439 meeting-pad pid-21439 I ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────── 2023-05-23 22:24:21.890 21439-21439 meeting-pad pid-21439 I │ Thread: main 2023-05-23 22:24:21.890 21439-21439 meeting-pad pid-21439 I ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ 2023-05-23 22:24:21.890 21439-21439 meeting-pad pid-21439 I │ Activity.onKeyUp (Activity.java:3784) 2023-05-23 22:24:21.890 21439-21439 meeting-pad pid-21439 I │ MainActivity.onBackPressed (MainActivity.java:70) 2023-05-23 22:24:21.890 21439-21439 meeting-pad pid-21439 I ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ 2023-05-23 22:24:21.890 21439-21439 meeting-pad pid-21439 I │ ---onBackPressed--- 2023-05-23 22:24:21.890 21439-21439 meeting-pad pid-21439 I └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
一切正常
再看看api文档
官方的态度也是不建议使用了
可以通过getOnBackPressedDispatcher的api来获取OnBackPressedDispatcher, 如果我在Fragment这个层级怎么办,可以使用requireActivity().getOnBackPressedDispatcher()
使用addCallback()方法来添加回调
推荐需要owner参数,可以有效控制“观察者”的有效性以及内存泄露问题,和LiveData的方式是一模一样的
OnBackPressedCallback的接口很简单,实现handleOnBackPressed方法即可,另外记得设置enabled,一般使用true。
有趣的Callback职责链模式 简而言之,就是你可以注册多个OnBackPressedCallback到OnBackPressedDispatcher。 但是这个Dispatcher只会执行一个,而且是“后发先至”的Stack模型。 职责链有点点太“高级”了,换一个类比,和军队指挥系统有点像 连长牺牲了,副连长上,副连长牺牲了,排长上~ 全牺牲,我就是连长了
代码测试
this.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { Logger.i("handleOnBackPressed11111"); } }); this.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { Logger.i("handleOnBackPressed22222"); } });
注册两个自定义Callback
回过头一想也是正确的,你把后退的职责抢过来了,那么什么都是自定义了,退堆这种事情也是自己来。你自己不做就没人做了!
既然我们增加了OnBackPressedCallback,原来默认的回调就被替换掉了。 让我们看看如果不加那么系统是怎么帮我们实现的吧
这里是更新状态,可以看到只有作为主导航控件+堆栈里面有值才会生效果,如果FragmentManager里面堆栈空了就不起效果了,交给外面的Activity来处理了,很合理
实现部分,可以看到退栈的逻辑 这里抛砖引玉下,感兴趣的可以直接看源码
优缺点 缺点:几乎没有 优点:接口灵活,还有层级优先级,装卸方便
总结 两套方案。官方文档说明了尽量不要混用,产生不必要的bug。
其实这次算是二刷自定义后退 第一次其实我没真正看懂~~
The text was updated successfully, but these errors were encountered:
upadte to #201
0fb3763
No branches or pull requests
关于“返回”的前世今生
其实最早接触到返回到概念是浏览器的
这小小的“后退”箭头按钮就是。
和他卧龙凤雏凑一堆的是“前进”
其实可以理解为对浏览记录的快捷跳转
如图所示
对于安卓的世界来说,返回堆栈就有Task 和 Activity的“宏观级别”
以及Framgment的“微观级别”
但是从用户体验角度上来讲,后退是“一致”的
另外现在安卓的发展也在往单Activity,多Framgment方向发展。
这个和Web前端的单页面方向很接近,殊途同归吧
关于干预“后退”按键的需求
虽然堆栈后退是常规操作。但是仍然有需要干预的可能和需要
操作体验的需要
比如第一个启动页面,如果按退出,整个app就“关”掉了。很多时候只是用户手滑(shou jian)了。
很多app,会提供一个提示,比如再按一次退出才真正退出。
业务方面考虑强需求
如果有的页面从业务角度讲就是必须不能后退的,必须完成后才能返回,比如登陆页,我首页又不允许匿名登陆的情况下。
确实需要自定义后退
比如当前的页面是一个内嵌了一个web浏览器,我点击后退。
“真实”的需求是我web后退一个页面,但是我把web页面直接给干掉了估计用户会很愤怒
关于返回键干预的具体方案
这应该是安卓的“经典”回调了
优点
简单粗暴,直接在Activity里面Override就行了,几乎没有其他啥操作
缺点
局限在Activity的逻辑中,如果需要Framgment参与就必须写额外的接口和通信,对于飞速发展的Framgment来说显然落后了。
例子
注意:这里super.onBackPressed();一定要调用,除非你想把后退功能给“裁剪”掉
一切正常
再看看api文档
官方的态度也是不建议使用了
可以通过getOnBackPressedDispatcher的api来获取OnBackPressedDispatcher,
如果我在Fragment这个层级怎么办,可以使用requireActivity().getOnBackPressedDispatcher()
使用addCallback()方法来添加回调
推荐需要owner参数,可以有效控制“观察者”的有效性以及内存泄露问题,和LiveData的方式是一模一样的
OnBackPressedCallback的接口很简单,实现handleOnBackPressed方法即可,另外记得设置enabled,一般使用true。
有趣的Callback职责链模式
简而言之,就是你可以注册多个OnBackPressedCallback到OnBackPressedDispatcher。
但是这个Dispatcher只会执行一个,而且是“后发先至”的Stack模型。
职责链有点点太“高级”了,换一个类比,和军队指挥系统有点像
连长牺牲了,副连长上,副连长牺牲了,排长上~
全牺牲,我就是连长了
代码测试
注册两个自定义Callback
很明显,后注册的“handleOnBackPressed22222”的日志打印了出来。 另外原来后退的功能“废”掉了回过头一想也是正确的,你把后退的职责抢过来了,那么什么都是自定义了,退堆这种事情也是自己来。你自己不做就没人做了!
既然我们增加了OnBackPressedCallback,原来默认的回调就被替换掉了。
让我们看看如果不加那么系统是怎么帮我们实现的吧
这里是更新状态,可以看到只有作为主导航控件+堆栈里面有值才会生效果,如果FragmentManager里面堆栈空了就不起效果了,交给外面的Activity来处理了,很合理
实现部分,可以看到退栈的逻辑
这里抛砖引玉下,感兴趣的可以直接看源码
优缺点
缺点:几乎没有
优点:接口灵活,还有层级优先级,装卸方便
总结
两套方案。官方文档说明了尽量不要混用,产生不必要的bug。
总结及相关链接
其实这次算是二刷自定义后退
第一次其实我没真正看懂~~
The text was updated successfully, but these errors were encountered: