• <kbd id="qyk40"></kbd>
  • <strike id="qyk40"></strike><samp id="qyk40"><pre id="qyk40"></pre></samp>

    Activity可以很容易的得到物理返回鍵的監聽事件,而Fragment卻不能。假設FragmentActivity有三個Fragment,一般安卓用戶期望點擊返回鍵會一層層返回到FragmentActivity。當然,我們可以將每個Fragment對應的Transaction放到BackStack中,但是如果每個Fragment有對返回事件的特殊消費,那么在FragmentActivity的onBackPressed()中的代碼就會比較混亂,例如:

    1. @Override
    2. public void onBackPressed() {
    3.     if(selectedFragment.equals(fragmentA) && fragmentA.hasExpandedRow()) {
    4.         fragmentA.collapseRow();
    5.     } else if(selectedFragment.equals(fragmentA) && fragmentA.isShowingLoginView()) {
    6.         fragmentA.hideLoginView();
    7.     } else if(selectedFragment.equals(fragmentA)) {
    8.         popBackStack();
    9.     } else if(selectedFragment.equals(fragmentB) && fragmentB.hasCondition1()) {
    10.         fragmentB.reverseCondition1();
    11.     } else if(selectedFragment.equals(fragmentB) && fragmentB.hasCondition2()) {
    12.         fragmentB.reverseCondition2();
    13.     } else if(selectedFragment.equals(fragmentB)) {
    14.         popBackStack();
    15.     } else {
    16.         // handle by activity
    17.         super.onBackPressed();
    18.     }
    19. }
    復制代碼

    這對于有代碼潔癖的程序猿顯然是不能容忍的,后來發現了一種優雅的解決方案。

     

    首先創建一個抽象類BackHandledFragment,該類有一個抽象方法onBackPressed(),所有BackHandledFragment的子類在onBackPressed方法中處理各自對Back事件的消費邏輯。onBackPressed返回布爾值,宿主FragmentActivity將會根據該方法的返回值判斷子Fragment是否有消費Back事件。此外,宿主FragmentActivity還會保持一份當前Fragment的引用,當用戶按下Back鍵時,宿主Activity會判斷當前Fragment是否需要消費該事件,如果沒有Fragment消費才會自己消費。

     

    1. public abstract class BackHandledFragment extends Fragment {
    2.  
    3.         protected BackHandledInterface mBackHandledInterface;
    4.         
    5.         /**
    6.          * 所有繼承BackHandledFragment的子類都將在這個方法中實現物理Back鍵按下后的邏輯
    7.          * FragmentActivity捕捉到物理返回鍵點擊事件后會首先詢問Fragment是否消費該事件
    8.          * 如果沒有Fragment消息時FragmentActivity自己才會消費該事件
    9.          */
    10.         protected abstract boolean onBackPressed();
    11.         
    12.         @Override
    13.         public void onCreate(Bundle savedInstanceState) {
    14.                 super.onCreate(savedInstanceState);
    15.                 if(!(getActivity() instanceof BackHandledInterface)){
    16.                         throw new ClassCastException("Hosting Activity must implement BackHandledInterface");
    17.                 }else{
    18.                         this.mBackHandledInterface = (BackHandledInterface)getActivity();
    19.                 }
    20.         }
    21.         
    22.         @Override
    23.         public void onStart() {
    24.                 super.onStart();
    25.                 //告訴FragmentActivity,當前Fragment在棧頂
    26.                 mBackHandledInterface.setSelectedFragment(this);
    27.         }
    28.         
    29. }
    復制代碼

    宿主FragmentActivity需要繼承BackHandledIntegerface,子Fragment會通過該接口告訴宿主FragmentActivity自己是當前屏幕可見的Fragment。

    1. public interface BackHandledInterface {
    2.  
    3.         public abstract void setSelectedFragment(BackHandledFragment selectedFragment);
    4. }
    復制代碼

    所以在Fragment的onCreate中會判斷宿主FragmentActivity是否已繼承了該接口。在Fragment的onStart()方法中就會調用該接口告訴宿主FragmentActivity自己是當前屏幕可見的Fragment。

    宿主FragmentActivity就可以在onBackPressed()方法中對Back事件進行判斷處理了。

    1. public class MainActivity extends FragmentActivity implements BackHandledInterface{
    2.  
    3.         private BackHandledFragment mBackHandedFragment;
    4.         private boolean hadIntercept;
    5.  
    6.         @Override
    7.         public void setSelectedFragment(BackHandledFragment selectedFragment) {
    8.                 this.mBackHandedFragment = selectedFragment;
    9.         }
    10.         
    11.         @Override
    12.         public void onBackPressed() {
    13.                 if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){
    14.                         if(getSupportFragmentManager().getBackStackEntryCount() == 0){
    15.                                 super.onBackPressed();
    16.                         }else{
    17.                                 getSupportFragmentManager().popBackStack();
    18.                         }
    19.                 }
    20.         }
    21. }
    復制代碼
    示例程序Github鏈接
    參考資料:

    Handling back button press Inside Fragments

    穩定

    產品高可用性高并發

    貼心

    項目群及時溝通

    專業

    產品經理1v1支持

    快速

    MVP模式小步快跑

    承諾

    我們選擇聲譽

    堅持

    10年專注高端品質開發
    • 返回頂部
    国产美女在线精品观看| 精品国产亚洲一区二区三区| 国产精品扒开腿做爽爽爽的视频| 久久人人做人人玩人精品| 久久中文字幕2021精品| 99久久国语露脸精品国产| 亚洲国产精品成人| 竹菊影视欧美日韩一区二区三区四区五区 | 青青青国产精品国产精品美女 | 一区二区不卡久久精品| 免费精品国产日韩热久久| 中文字幕国产日韩| 国产精品亚洲а∨无码播放麻豆| 日韩精品无码久久一区二区三| 精品人妻少妇一区二区三区在线| 日韩高清免费在线观看| 日韩一级特黄av毛片| 国产精品9999久久久久仙踪林| 合区精品中文字幕| 国产成人亚洲精品狼色在线| 欧美日韩精品一区二区在线观看| 中文字幕日韩理论在线| 国产av无码久久精品| 国产成人精品男人的天堂网站 | 久久久久久国产精品美女| 国产精品高清在线| 国产精品国产三级在线高清观看| 亚洲色图国产精品| 精品国产高清久久久久久小说| 国产精品国产三级国产an| 国产成人午夜精品影院游乐网| 好吊妞视频这里有精品| 国产精品夜间视频香蕉| 一本色道久久88—综合亚洲精品 | 亚洲精品成人图区| 久久精品人人槡人妻人人玩AV| 99re这里有免费视频精品| 99久久人妻精品免费二区| 久久精品国产亚洲AV电影| 揄拍自拍日韩精品| 99精品众筹模特私拍在线|