Android 在fragment中实现返回键单击提醒 双击退出

尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成。

项目地址

接近完成的时候,想在天气信息页面实现一个很常见的功能,也就是点击屏幕下方的返回键的时候不是返回到上一个activity或者退出,而是提醒用户再按一次就会退出。

实现思路也很简单,就是对返回键的动作进行监听和拦截,然后重写成需要的动作,因为在我的程序中activity只作为调度器使用,真正的View功能在fragment中,所以返回键的动作捕捉只能以接口形式

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‘
时间: 2024-08-28 10:49:02

Android 在fragment中实现返回键单击提醒 双击退出的相关文章

在fragment中实现返回键单击提醒 双击退出

最近在练习一个小项目,也就是郭霖大神的开源天气程序,尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成. 项目地址 接近完成的时候,想在天气信息页面实现一个很常见的功能,也就是点击屏幕下方的返回键的时候不是返回到上一个activity或者退出,而是提醒用户再按一次就会退出. 实现思路也很简单,就是对返回键的动作进行监听和拦截,然后重写成需要的动作,因为在我的程序中activity只作为调度器使用,真正的View功能在fragment中,所以返回键的动作捕捉只能以接口形

大叔也说Xamarin~Android篇~监听返回键,单击返回某个webView,双击退出

原文:大叔也说Xamarin~Android篇~监听返回键,单击返回某个webView,双击退出 这个操作在原生android里是很容易实现的,在xamarin里也不难,在activity里有方法OnKeyDown,我们只需要重写一下就可以了,然后通过webView重新加载到要返回的页面即可,当然操作有些死板,但还是有着不错的效果! 实现的原理就是在activity里设置一个时间,单击后把这个时间赋值并与当前时间进行比较,如果在2秒内,就认为是双击操作,当然这个时间间隔你可以自己设置,在认为是双

android中的返回键与Activity

我在做应用时遇到一个问题,就是在启动主页面时需要预先加载一些数据,我是在一个加载页中处理完这些数据然后再转到主页面,但当我在主页面中按返回键时,系统会返回加载页面.我不希望加载页在使用完之后还被保留在任务中. Android的官方文档中这样描述的返回栈.任务和activity的默认关系: 1:当从Activity A中启动Activity B时,Activity A停止,但是保存了它的状态(比如,滚动位置和表单中的文字).如果当用户在Activity B中按了返回键,Activity A会恢复之

Android的Fragment中的互相通信-桥梁activity

Android的Fragment中的互相通信-桥梁activity 效果图如下: 项目结构图如下: Fragment1: package com.demo.fragmenttongxin; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import an

返回键捕获 应用程序退出的两种方式(转)

作为应用程序一个较好的用户体验应该是:在退出应用程序前询问用户是否真正退出?目前普遍做法是,一在退出前询问是否真正退出,二是连续按两下退出. 返回键捕获 应用程序退出的两种方式 实现上述两种应用退出方式需要在onkeyDown()来进行捕获返回键 在Activity中,如果需要动态注册广播官方文档建议在onResume()进行注册,在onPause()中取消注册.注册部分代码如下: 应用程序退出方式一:确认退出对话框 public boolean onKeyDown(int keyCode, K

android fragment点击返回键实现内容切换?

============问题描述============ 我有一个fragment,上有一个button和textview,默认button是隐藏的,通过点击菜单栏上的一个详细信息的按钮,将button显示出来,现在有没有办法通过点击返回键实现返回上一个只有textview的页面??? ============解决方案1============ 在Activity中重写onBackPress坚挺返回按钮事件 ============解决方案2============ 将fragment添加到回退

Android必知必会-Fragment监听返回键事件

如果移动端访问不佳,请尝试 Github版<–点击左侧 背景 项目要求用户注册成功后进入修改个人资料的页面,且不允许返回到上一个页面,资料修改完成后结束当前页面,进入APP主页. 由于是使用多个Fragment完成注册流程,就需要Fragment监听用户点击手机上的返回按钮,查了一些资料,加上自己使用过程中发现的问题,特此记录,帮助更多有此需求的朋友 代码实现 XXX_Fragment @Override public void onResume() { super.onResume(); ge

Android 优雅的让Fragment监听返回键

Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentActivity.当然,我们可以将每个Fragment对应的Transaction放到BackStack中,但是如果每个Fragment有对返回事件的特殊消费,那么在FragmentActivity的onBackPressed()中的代码就会比较混乱,例如: @Override public void

优雅的让Fragment监听返回键

Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentActivity.当然,我们可以将每个Fragment对应的Transaction放到BackStack中,但是如果每个Fragment有对返回事件的特殊消费,那么在FragmentActivity的onBackPressed()中的代码就会比较混乱,例如: [java] view plaincopy