在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'  

本人水平有限,之前很少寫博客,以后會盡量堅持更新,分享學習心得,歡迎交流。

 

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM