91亚洲精华国内精华精华液_国产高清在线精品一区不卡_精品特级一级毛片免费观看_欧美日韩中文制服有码_亚洲精品无码你懂的网站369

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

  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. }
復(fù)制代碼

這對(duì)于有代碼潔癖的程序猿顯然是不能容忍的,后來發(fā)現(xiàn)了一種優(yōu)雅的解決方案。

 

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

 

  1. public abstract class BackHandledFragment extends Fragment {
  2.  
  3.         protected BackHandledInterface mBackHandledInterface;
  4.         
  5.         /**
  6.          * 所有繼承BackHandledFragment的子類都將在這個(gè)方法中實(shí)現(xiàn)物理Back鍵按下后的邏輯
  7.          * FragmentActivity捕捉到物理返回鍵點(diǎn)擊事件后會(huì)首先詢問Fragment是否消費(fèi)該事件
  8.          * 如果沒有Fragment消息時(shí)FragmentActivity自己才會(huì)消費(fèi)該事件
  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,當(dāng)前Fragment在棧頂
  26.                 mBackHandledInterface.setSelectedFragment(this);
  27.         }
  28.         
  29. }
復(fù)制代碼

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

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

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

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

  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. }
復(fù)制代碼
示例程序Github鏈接
參考資料:

Handling back button press Inside Fragments

穩(wěn)定

產(chǎn)品高可用性高并發(fā)

貼心

項(xiàng)目群及時(shí)溝通

專業(yè)

產(chǎn)品經(jīng)理1v1支持

快速

MVP模式小步快跑

承諾

我們選擇聲譽(yù)

堅(jiān)持

10年專注高端品質(zhì)開發(fā)
  • 返回頂部