在fragment中实现返回键单击提醒 双击退出
最近在练习一个小项目,也就是郭霖大神的开源天气程序,尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成。
接近完成的时候,想在天气信息页面实现一个很常见的功能,也就是点击屏幕下方的返回键的时候不是返回到上一个activity或者退出,而是提醒用户再按一次就会退出。
实现思路也很简单,就是对返回键的动作进行监听和拦截,然后重写成需要的动作,因为在我的程序中activity只作为调度器使用,真正的View功能在fragment中,所以返回键的动作捕捉只能以接口形式写在BaseActivity中,然后让BaseFragment实现这个接口,代码如下:
- public class BaseActivity extends AppCompatActivity {
 - protected final String TAG = this.getClass().getSimpleName();
 - @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - ActivityCollector.addActivity(this);
 - }
 - @Override
 - protected void onDestroy() {
 - super.onDestroy();
 - ActivityCollector.removeActivity(this);
 - }
 - //返回键监听实现
 - interface FragmentBackListener {
 - void onBackForward();
 - }
 - private FragmentBackListener backListener;
 - private boolean isInterception = false;
 - public void setBackListener(FragmentBackListener backListener) {
 - this.backListener = backListener;
 - }
 - //是否拦截
 - public boolean isInterception() {
 - return isInterception;
 - }
 - public void setInterception(boolean isInterception) {
 - this.isInterception = isInterception;
 - }
 - @Override
 - public boolean onKeyDown(int keyCode, KeyEvent event) {
 - if (keyCode == KeyEvent.KEYCODE_BACK) {
 - if (isInterception()) {
 - if (backListener != null) {
 - backListener.onBackForward();
 - return false;
 - }
 - }
 - }
 - return super.onKeyDown(keyCode, event);
 - }
 - }
 
- public abstract class BaseFragment extends Fragment implements BaseActivity.FragmentBackListener {
 - protected Disposable disposable;
 - protected final String TAG = this.getClass().getSimpleName();
 - //返回键点击间隔时间计算
 - private long exitTime = 0;
 - //捕捉返回键点击动作
 - @Override
 - public void onBackForward() {
 - //和上次点击返回键的时间间隔
 - long intervalTime = System.currentTimeMillis() - exitTime;
 - if (intervalTime > 2000) {
 - Toast.makeText(getActivity(), getString(R.string.exit_toast), Toast.LENGTH_SHORT).show();
 - exitTime = System.currentTimeMillis();
 - } else {
 - ActivityCollector.finishAll();
 - }
 - }
 - @Override
 - public void onAttach(Context context) {
 - super.onAttach(context);
 - //注册监听
 - ((BaseActivity) getActivity()).setBackListener(this);
 - ((BaseActivity) getActivity()).setInterception(true);
 - }
 - @Override
 - public void onDetach() {
 - super.onDetach();
 - //取消监听
 - ((BaseActivity) getActivity()).setBackListener(null);
 - ((BaseActivity) getActivity()).setInterception(false);
 - }
 - @Override
 - public void onDestroyView() {
 - super.onDestroyView();
 - unsubscribe();
 - }
 - protected void unsubscribe() {
 - if (disposable != null && !disposable.isDisposed()) {
 - disposable.dispose();
 - }
 - }
 - }
 
通过一个ActivityCollector来管理活动:
- public class ActivityCollector {
 - public static List<Activity> activities = new ArrayList<>();
 - public static void addActivity(Activity activity) {
 - activities.add(activity);
 - }
 - public static void removeActivity(Activity activity) {
 - activities.remove(activity);
 - }
 - public static void finishAll() {
 - for (Activity activity : activities) {
 - if (!activity.isFinishing()) {
 - activity.finish();
 - }
 - }
 - }
 - }
 
这样,所有继承BaseFragment的fragment都回拥有这个单击提醒 双击退出的功能了,代码不复杂,也带有注释,相信很容易看懂。
如果某个页面不需要这个功能可以在fragment中重写BaseFragment中的onAttach方法
- @Override
 - public void onAttach(Context context) {
 - super.onAttach(context);
 - ((BaseActivity) getActivity()).setInterception(false);
 - }
 
当然如果手机应用的大多数页面不需要这个功能,可以在BaseFragment中默认关闭拦截,在需要用的fragment中重写onAttach来打开。
最后说一点我在开发过程中遇到的小坑,在网络访问的功能方面我使用了squareup的retrofit2和okhttp
一开始我在build.gradle是这么配置的
- //squareup dependencies
 - compile 'com.squareup.okhttp3:okhttp:3.6.0'
 - compile 'com.squareup.okio:okio:1.11.0'
 - compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
 - compile 'com.squareup.retrofit2:retrofit:2.2.0'
 - compile 'com.squareup.retrofit2:converter-gson:2.2.0'
 - compile 'com.squareup.retrofit2:converter-scalars:2.2.0'
 - compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0'
 - //RxJava dependencies
 - compile 'io.reactivex.rxjava2:rxandroid:2.0.0'
 - compile 'io.reactivex.rxjava2:rxjava:2.0.2'
 
但是编译的时候无法通过,
经过排查,原因是retrofit2自带的rxjava适配器还未升级到rxjava2,所以产生了编译错误,解决办法也不复杂Jake大神给我写了一个rxjava2的适配器,替换原来的就可以了:
- //squareup dependencies
 - compile 'com.squareup.okhttp3:okhttp:3.6.0'
 - compile 'com.squareup.okio:okio:1.11.0'
 - compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
 - compile 'com.squareup.retrofit2:retrofit:2.2.0'
 - compile 'com.squareup.retrofit2:converter-gson:2.2.0' //gson转化器
 - compile 'com.squareup.retrofit2:converter-scalars:2.2.0'//String转化器
 - compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
 - //RxJava dependencies
 - compile 'io.reactivex.rxjava2:rxandroid:2.0.0'
 - compile 'io.reactivex.rxjava2:rxjava:2.0.2'
 
本人水平有限,之前很少写博客,以后会尽量坚持更新,分享学习心得,欢迎交流。
在fragment中实现返回键单击提醒 双击退出的更多相关文章
- Android 在fragment中实现返回键单击提醒 双击退出
		
尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成. 项目地址 接近完成的时候,想在天气信息页面实现一个很常见的功能,也就是点击屏幕下方的返回键的时候不是返回到上一个act ...
 - 在Fragment 中拦截返回键
		
代码如下: class XXXFrgmt : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ...
 - android中的返回键与Activity
		
我在做应用时遇到一个问题.就是在启动主页面时须要预先载入一些数据.我是在一个载入页中处理完这些数据然后再转到主页面.但当我在主页面中按返回键时,系统会返回载入页面.我不希望载入页在使用完之 ...
 - 让Fragment监听返回键
		
Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.所以使用到了以下的方法. 首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPre ...
 - Fragment监听返回键
		
首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对 ...
 - 优雅的让Fragment监听返回键
		
转载请注明出处:http://write.blog.csdn.net/postedit/40507387 Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设Fragm ...
 - Android必知必会-Fragment监听返回键事件
		
如果移动端访问不佳,请尝试 Github版<–点击左侧 背景 项目要求用户注册成功后进入修改个人资料的页面,且不允许返回到上一个页面,资料修改完成后结束当前页面,进入APP主页. 由于是使用多个 ...
 - Android 优雅的让Fragment监听返回键
		
Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentAc ...
 - Coco2d-js/Cocos2d-html5中Android返回键实现
		
导语: 首先Cocos2d-x其中实现Menu和Back按键相对简单一点,而在资源较少的Cocos2d-html5其中.要实现返回还是有一点不一样的,并且有没有详细的demo.也就仅仅有自己去看api ...
 
随机推荐
- Python爬虫教程:requests模拟登陆github
			
1. Cookie 介绍 HTTP 协议是无状态的.因此,若不借助其他手段,远程的服务器就无法知道以前和客户端做了哪些通信.Cookie 就是「其他手段」之一. Cookie 一个典型的应用场景,就是 ...
 - 13 DFT变换的性质
			
DFT变换的性质 线性性质 \[ \begin{aligned} y[n]&=ax[n]+bw[n]\xrightarrow{DFT}Y[k]=\sum_{n=0}^{N-1}(ax[n]+ ...
 - 基于MACVLAN配置VMWARE虚拟机中容器网络
			
基于MACVLAN配置VMWARE虚拟机中容器网络 测试部环境组 201711 0 文档说明 MACVLAN是docker的一种支持跨主机网络的driver.macvlan本身是linux kerne ...
 - docker安装-单机/多机安装
			
操作系统ubuntu14.04 16.04 v单机安装步骤: #安装httpsca证书 apt-get install apt-transport-https ca-certificates #添 ...
 - buuctf——facebook1
			
分为注册和登陆两个页面 据大佬wp登陆页面又盲注,但我没测试 直接注册后登陆 注册后发现,会显示输入的url 根据目录扫描,发现robots.txt和flag.php robots.txt有源码备份 ...
 - Django框架之ORM对表结构操作
			
ORM的优点:(1)简单,不用自己写SQL语句 (2)开发效率高 ORM的缺点:对于不同的人写的代码,执行效率有差别 ORM的对应关系: 类 ----------> 数据表 对象------ ...
 - 【代码总结】MYSQL数据库的常见操作
			
============================== MYSQL数据库的常见操作 ============================== 一.mysql的连接与关闭 -h:指定所连接的服 ...
 - 吴裕雄 python 神经网络——TensorFlow训练神经网络:不使用激活函数
			
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data INPUT_NODE = 784 ...
 - java 抛出异常与finally的混用对于语句块的执行顺序的影响
			
代码如下: package test1; public class EmbededFinally { public static void main(String args[]) { int resu ...
 - Promise解决回调地狱(多层调用问题)
			
Promise # Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息:从本意上讲,它是承诺,承诺它过一段时间会给你一个结果.promise有三 ...