首先創建一個抽象類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 public abstract void setSelectedFragment(BackHandledFragment selectedFragment); 3 }
所以在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 }
DEMO完整下載地址:https://github.com/mxy1228/FragmentHandleBackDemo/
http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/