• <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年專注高端品質開發
    • 返回頂部
    无码人妻精品一区二区三区9厂| 国产成人精品日本亚洲11| 日韩影视在线观看| 精品中文字幕久久久久久| 国产夫妇精品自在线| 久久久免费精品re6| 久久国产精品99久久久久久老狼| 国产免费久久精品99久久| 日韩在线a视频免费播放| 日韩在线观看网站| 国产精品一区二区电影| 成人精品一区二区三区校园激情 | 久久国产精品-久久精品| 中文字幕日韩专区精品系列| 亚洲国产一成久久精品国产成人综合 | 国产精品国产高清国产专区| 亚洲AV日韩AV天堂久久| 国产精品一区二区久久沈樵| 青青国产精品视频| 国产精品亚洲一区二区在线观看 | 国产精品二区在线| 国产精品香蕉成人网在线观看| 久久精品国产亚洲av天美18| 亚洲精品乱码久久久久久蜜桃图片| 国产四虎免费精品视频| 日本国产成人精品视频| 精品欧洲AV无码一区二区男男| 2021国内精品久久久久影院| 在线观看91精品国产入口| 精品一区二区三区无码免费视频| 99精品在线视频观看| 久久亚洲精品无码AV红樱桃| 亚洲国产精品自在线一区二区| 久久99精品久久久久久园产越南| 国产精品99精品无码视亚| 久久精品韩国三级| 无码国内精品人妻少妇| 久久亚洲精精品中文字幕| 亚洲精品视频在线观看免费| 亚洲国产精品一区二区久| 免费精品国产自产拍在线观看图片|