最近在练习一个小项目,也就是郭霖大神的开源天气程序,尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成。

项目地址

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

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

  1. public class BaseActivity extends AppCompatActivity {
  2. protected final String TAG = this.getClass().getSimpleName();
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. ActivityCollector.addActivity(this);
  7. }
  8. @Override
  9. protected void onDestroy() {
  10. super.onDestroy();
  11. ActivityCollector.removeActivity(this);
  12. }
  13. //返回键监听实现
  14. interface FragmentBackListener {
  15. void onBackForward();
  16. }
  17. private FragmentBackListener backListener;
  18. private boolean isInterception = false;
  19. public void setBackListener(FragmentBackListener backListener) {
  20. this.backListener = backListener;
  21. }
  22. //是否拦截
  23. public boolean isInterception() {
  24. return isInterception;
  25. }
  26. public void setInterception(boolean isInterception) {
  27. this.isInterception = isInterception;
  28. }
  29. @Override
  30. public boolean onKeyDown(int keyCode, KeyEvent event) {
  31. if (keyCode == KeyEvent.KEYCODE_BACK) {
  32. if (isInterception()) {
  33. if (backListener != null) {
  34. backListener.onBackForward();
  35. return false;
  36. }
  37. }
  38. }
  39. return super.onKeyDown(keyCode, event);
  40. }
  41. }
  1. public abstract class BaseFragment extends Fragment implements BaseActivity.FragmentBackListener {
  2. protected Disposable disposable;
  3. protected final String TAG = this.getClass().getSimpleName();
  4. //返回键点击间隔时间计算
  5. private long exitTime = 0;
  6. //捕捉返回键点击动作
  7. @Override
  8. public void onBackForward() {
  9. //和上次点击返回键的时间间隔
  10. long intervalTime = System.currentTimeMillis() - exitTime;
  11. if (intervalTime > 2000) {
  12. Toast.makeText(getActivity(), getString(R.string.exit_toast), Toast.LENGTH_SHORT).show();
  13. exitTime = System.currentTimeMillis();
  14. } else {
  15. ActivityCollector.finishAll();
  16. }
  17. }
  18. @Override
  19. public void onAttach(Context context) {
  20. super.onAttach(context);
  21. //注册监听
  22. ((BaseActivity) getActivity()).setBackListener(this);
  23. ((BaseActivity) getActivity()).setInterception(true);
  24. }
  25. @Override
  26. public void onDetach() {
  27. super.onDetach();
  28. //取消监听
  29. ((BaseActivity) getActivity()).setBackListener(null);
  30. ((BaseActivity) getActivity()).setInterception(false);
  31. }
  32. @Override
  33. public void onDestroyView() {
  34. super.onDestroyView();
  35. unsubscribe();
  36. }
  37. protected void unsubscribe() {
  38. if (disposable != null && !disposable.isDisposed()) {
  39. disposable.dispose();
  40. }
  41. }
  42. }

通过一个ActivityCollector来管理活动:

  1. public class ActivityCollector {
  2. public static List<Activity> activities = new ArrayList<>();
  3. public static void addActivity(Activity activity) {
  4. activities.add(activity);
  5. }
  6. public static void removeActivity(Activity activity) {
  7. activities.remove(activity);
  8. }
  9. public static void finishAll() {
  10. for (Activity activity : activities) {
  11. if (!activity.isFinishing()) {
  12. activity.finish();
  13. }
  14. }
  15. }
  16. }

这样,所有继承BaseFragment的fragment都回拥有这个单击提醒 双击退出的功能了,代码不复杂,也带有注释,相信很容易看懂。

如果某个页面不需要这个功能可以在fragment中重写BaseFragment中的onAttach方法

  1. @Override
  2. public void onAttach(Context context) {
  3. super.onAttach(context);
  4. ((BaseActivity) getActivity()).setInterception(false);
  5. }

当然如果手机应用的大多数页面不需要这个功能,可以在BaseFragment中默认关闭拦截,在需要用的fragment中重写onAttach来打开。

最后说一点我在开发过程中遇到的小坑,在网络访问的功能方面我使用了squareup的retrofit2和okhttp

一开始我在build.gradle是这么配置的

  1. //squareup dependencies
  2. compile 'com.squareup.okhttp3:okhttp:3.6.0'
  3. compile 'com.squareup.okio:okio:1.11.0'
  4. compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
  5. compile 'com.squareup.retrofit2:retrofit:2.2.0'
  6. compile 'com.squareup.retrofit2:converter-gson:2.2.0'
  7. compile 'com.squareup.retrofit2:converter-scalars:2.2.0'
  8. compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0'
  9. //RxJava dependencies
  10. compile 'io.reactivex.rxjava2:rxandroid:2.0.0'
  11. compile 'io.reactivex.rxjava2:rxjava:2.0.2'

但是编译的时候无法通过,

经过排查,原因是retrofit2自带的rxjava适配器还未升级到rxjava2,所以产生了编译错误,解决办法也不复杂Jake大神给我写了一个rxjava2的适配器,替换原来的就可以了:

  1. //squareup dependencies
  2. compile 'com.squareup.okhttp3:okhttp:3.6.0'
  3. compile 'com.squareup.okio:okio:1.11.0'
  4. compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
  5. compile 'com.squareup.retrofit2:retrofit:2.2.0'
  6. compile 'com.squareup.retrofit2:converter-gson:2.2.0' //gson转化器
  7. compile 'com.squareup.retrofit2:converter-scalars:2.2.0'//String转化器
  8. compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
  9. //RxJava dependencies
  10. compile 'io.reactivex.rxjava2:rxandroid:2.0.0'
  11. compile 'io.reactivex.rxjava2:rxjava:2.0.2'

本人水平有限,之前很少写博客,以后会尽量坚持更新,分享学习心得,欢迎交流。

 
 

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

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

    尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成. 项目地址 接近完成的时候,想在天气信息页面实现一个很常见的功能,也就是点击屏幕下方的返回键的时候不是返回到上一个act ...

  2. 在Fragment 中拦截返回键

    代码如下: class XXXFrgmt : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ...

  3. android中的返回键与Activity

          我在做应用时遇到一个问题.就是在启动主页面时须要预先载入一些数据.我是在一个载入页中处理完这些数据然后再转到主页面.但当我在主页面中按返回键时,系统会返回载入页面.我不希望载入页在使用完之 ...

  4. 让Fragment监听返回键

    Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.所以使用到了以下的方法. 首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPre ...

  5. Fragment监听返回键

    首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对 ...

  6. 优雅的让Fragment监听返回键

    转载请注明出处:http://write.blog.csdn.net/postedit/40507387 Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设Fragm ...

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

    如果移动端访问不佳,请尝试 Github版<–点击左侧 背景 项目要求用户注册成功后进入修改个人资料的页面,且不允许返回到上一个页面,资料修改完成后结束当前页面,进入APP主页. 由于是使用多个 ...

  8. Android 优雅的让Fragment监听返回键

    Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentAc ...

  9. Coco2d-js/Cocos2d-html5中Android返回键实现

    导语: 首先Cocos2d-x其中实现Menu和Back按键相对简单一点,而在资源较少的Cocos2d-html5其中.要实现返回还是有一点不一样的,并且有没有详细的demo.也就仅仅有自己去看api ...

随机推荐

  1. 最新版自动检测卡片类型工具软件版本(auto check card type v3.2.0)

    自动检测卡片类型工具软件. 卡片放到读卡器上面自动识别卡片类型,不需老是按下按钮,好用,方便.支持自动识别NTAG213卡片,NTAG215卡片, NTAG216卡片,Ultralight芯片, Ul ...

  2. webpack原理类型问题

    1.webpack底层原理 (实现一个webpack) 步骤:1.拿到入口文件的代码并读出来转化为js对象(抽象语法术parser)2.拿到所有模块的依赖 ‘./message.js’,放进数组中 引 ...

  3. http协议学习 —— post请求方法提交application/x-www-form-urlencoded类型的数据格式

    先推荐一篇很不错的文章:https://imququ.com/post/four-ways-to-post-data-in-http.html 说一下,如果是自己编写底层,那么要注意了,不能只有提交数 ...

  4. Centos6.X创建Oracle用户

    第一步:创建数据表空间 第二步:创建临时表空间 第三步:创建用户并指定表空间 第四步:给用户授予权限 1.创建数据表空间 格式: create tablespace 表间名 datafile ‘数据文 ...

  5. HackInOS靶机渗透

    一.环境配置 攻击机kali搭建在Vmware,桥接模式,ip:192.168.43.48 靶机HackInOS需要用VirtualBox导入ova文件,桥接模式,启动完成之后, 选择Ubuntu系统 ...

  6. 「JSOI2011」任务调度

    「JSOI2011」任务调度 传送门 一开始还在想写平衡树,看到 \(\text{TRANS}\) 操作后就晓得要用可并堆了. 这题好像就是个可并堆的板子题??? ADD 直接往对应的对里面加元素 D ...

  7. Java自学-集合框架 ArrayList和LinkedList的区别

    ArrayList和LinkedList的区别 步骤 1 : ArrayList和LinkedList的区别 ArrayList ,插入,删除数据慢 LinkedList, 插入,删除数据快 Arra ...

  8. 【LOJ3087】「GXOI / GZOI2019」旅行者

    题意 给定一个 \(n\) 个点 \(m\) 条边的的有向图,给出 \(k\) 个关键点,求关键点两两最短路的最小值. \(n\le 10^5, m\le 5\cdot 10^5\). 题解 二进制分 ...

  9. 十三 Spring的通知类型,切入表达式写法

    Spring中通知类型: 前置通知:目标方法执行之前进行操作,可以获得切入点信息 后置通知: 目标方法执行之后进行操作,可以获得方法的返回值 环绕通知:在目标方法执行之前和之后进行操作,可以终止目标方 ...

  10. 学习笔记(6)- pytext训练会话助手

    https://github.com/facebookresearch/pytext https://pytext.readthedocs.io/en/master/ https://pytext.r ...