zoukankan      html  css  js  c++  java
  • 在fragment中实现返回键单击提醒 双击退出

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

    项目地址 

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

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

    [java] view plain copy
    1.    public class BaseActivity extends AppCompatActivity {  
    2.     protected final String TAG = this.getClass().getSimpleName();  
    3.   
    4.     @Override  
    5.     protected void onCreate(Bundle savedInstanceState) {  
    6.         super.onCreate(savedInstanceState);  
    7.         ActivityCollector.addActivity(this);  
    8.     }  
    9.   
    10.     @Override  
    11.     protected void onDestroy() {  
    12.         super.onDestroy();  
    13.         ActivityCollector.removeActivity(this);  
    14.     }  
    15.   
    16.     //返回键监听实现  
    17.     interface FragmentBackListener {  
    18.         void onBackForward();  
    19.     }  
    20.   
    21.     private FragmentBackListener backListener;  
    22.     private boolean isInterception = false;  
    23.   
    24.     public void setBackListener(FragmentBackListener backListener) {  
    25.         this.backListener = backListener;  
    26.     }  
    27.     //是否拦截  
    28.     public boolean isInterception() {  
    29.         return isInterception;  
    30.     }  
    31.   
    32.     public void setInterception(boolean isInterception) {  
    33.         this.isInterception = isInterception;  
    34.     }  
    35.   
    36.     @Override  
    37.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
    38.         if (keyCode == KeyEvent.KEYCODE_BACK) {  
    39.             if (isInterception()) {  
    40.                 if (backListener != null) {  
    41.                     backListener.onBackForward();  
    42.                     return false;  
    43.                 }  
    44.             }  
    45.         }  
    46.         return super.onKeyDown(keyCode, event);  
    47.     }  
    48. }  

    [java] view plain copy
    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.     //捕捉返回键点击动作  
    8.     @Override  
    9.     public void onBackForward() {  
    10.         //和上次点击返回键的时间间隔  
    11.         long intervalTime = System.currentTimeMillis() - exitTime;  
    12.         if (intervalTime > 2000) {  
    13.             Toast.makeText(getActivity(), getString(R.string.exit_toast), Toast.LENGTH_SHORT).show();  
    14.             exitTime = System.currentTimeMillis();  
    15.         } else {  
    16.             ActivityCollector.finishAll();  
    17.         }  
    18.     }  
    19.   
    20.     @Override  
    21.     public void onAttach(Context context) {  
    22.         super.onAttach(context);  
    23.         //注册监听  
    24.         ((BaseActivity) getActivity()).setBackListener(this);  
    25.         ((BaseActivity) getActivity()).setInterception(true);  
    26.     }  
    27.   
    28.     @Override  
    29.     public void onDetach() {  
    30.         super.onDetach();  
    31.         //取消监听  
    32.         ((BaseActivity) getActivity()).setBackListener(null);  
    33.         ((BaseActivity) getActivity()).setInterception(false);  
    34.     }  
    35.   
    36.     @Override  
    37.     public void onDestroyView() {  
    38.         super.onDestroyView();  
    39.         unsubscribe();  
    40.     }  
    41.   
    42.     protected void unsubscribe() {  
    43.         if (disposable != null && !disposable.isDisposed()) {  
    44.             disposable.dispose();  
    45.         }  
    46.     }  
    47.   
    48. }  
    通过一个ActivityCollector来管理活动:
    [java] view plain copy
    1. public class ActivityCollector {  
    2.     public static List<Activity> activities = new ArrayList<>();  
    3.   
    4.     public static void addActivity(Activity activity) {  
    5.         activities.add(activity);  
    6.     }  
    7.   
    8.     public static void removeActivity(Activity activity) {  
    9.         activities.remove(activity);  
    10.     }  
    11.   
    12.     public static void finishAll() {  
    13.         for (Activity activity : activities) {  
    14.             if (!activity.isFinishing()) {  
    15.                 activity.finish();  
    16.             }  
    17.         }  
    18.     }  
    19. }  

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

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

    [java] view plain copy
    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是这么配置的

    [html] view plain copy
    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.   
    6. compile 'com.squareup.retrofit2:retrofit:2.2.0'  
    7. compile 'com.squareup.retrofit2:converter-gson:2.2.0'  
    8. compile 'com.squareup.retrofit2:converter-scalars:2.2.0'  
    9. compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0'  
    10.   
    11. //RxJava dependencies  
    12. compile 'io.reactivex.rxjava2:rxandroid:2.0.0'  
    13. compile 'io.reactivex.rxjava2:rxjava:2.0.2'  
    但是编译的时候无法通过,



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

    [html] view plain copy
    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.   
    6. compile 'com.squareup.retrofit2:retrofit:2.2.0'  
    7. compile 'com.squareup.retrofit2:converter-gson:2.2.0' //gson转化器  
    8. compile 'com.squareup.retrofit2:converter-scalars:2.2.0'//String转化器  
    9. compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'  
    10.   
    11. //RxJava dependencies  
    12. compile 'io.reactivex.rxjava2:rxandroid:2.0.0'  
    13. compile 'io.reactivex.rxjava2:rxjava:2.0.2'  

    本人水平有限,之前很少写博客,以后会尽量坚持更新,分享学习心得,欢迎交流。
     
     
  • 相关阅读:
    新能源汽车产业发展规划(2021-2035年)
    Spire.Doc 生成长图
    【Kafka】单机Kafka测试
    【Linux】IO多路复用之select、poll、epoll模型
    【Linux】五种IO模型
    【Linux】零拷贝技术(Zero Copy)
    【Linux】系统相关概念
    【SpringBoot】SpringBoot 整合Redisson
    【Spring】SpringBoot + SpringSession + Redis 实现Session共享
    【SpringBoot】SpringBoot 整合Redis
  • 原文地址:https://www.cnblogs.com/lenkevin/p/7614671.html
Copyright © 2011-2022 走看看