Activity 比較容易監(jiān)聽(tīng)物理鍵返回事件(onBackPressed)嘱朽;Fragment卻不能
假設(shè)一個(gè)FragmentActivity包含3個(gè)Fragment栏渺,用戶一般期望在返回時(shí),逐層返回到FragmentActivity穴店,當(dāng)然我們可以將每個(gè)Fragment對(duì)應(yīng)的Transaction放到BackStack當(dāng)中撕捍,但是如果每個(gè)Fragment有對(duì)返回事件的特殊消費(fèi),如何優(yōu)雅的實(shí)現(xiàn)了泣洞?
- 首先創(chuàng)建一個(gè)抽象類BaseHandleFragment忧风,該類有一個(gè)抽象方法onBackPressed方法,所有子Fragment繼承于他球凰,實(shí)現(xiàn)該方法處理各自對(duì)Back事件的消費(fèi)邏輯狮腿,該方法返回一個(gè)布爾值腿宰,宿主FragmentActivity將會(huì)根據(jù)該方法返回值判斷子Fragment是否有消費(fèi)Back事件
public abstract class BackHandledFragment extends Fragment {
protected BackHandledInterface mBackHandledInterface;
/**
* 所有繼承BackHandledFragment的子類都將在這個(gè)方法中實(shí)現(xiàn)物理Back鍵按下后的邏輯
* FragmentActivity捕捉到物理返回鍵點(diǎn)擊事件后會(huì)首先詢問(wèn)Fragment是否消費(fèi)該事件
* 如果沒(méi)有Fragment消息時(shí)FragmentActivity自己才會(huì)消費(fèi)該事件
*/
protected abstract boolean onBackPressed();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!(getActivity() instanceof BackHandledInterface)){
throw new ClassCastException("Hosting Activity must implement BackHandledInterface");
}else{
this.mBackHandledInterface = (BackHandledInterface)getActivity();
}
}
@Override
public void onStart() {
super.onStart();
//告訴FragmentActivity,當(dāng)前Fragment在棧頂
mBackHandledInterface.setSelectedFragment(this);
}
}
2.宿主Activity將會(huì)保存一份當(dāng)前Fragment的引用缘厢,當(dāng)用戶按下Back鍵時(shí)吃度,Activity會(huì)通過(guò)上述1中onBackPressed的返回值,判斷該Fragment是否有消費(fèi)該事件贴硫,沒(méi)有才會(huì)自己消費(fèi)
3.宿主FragmentActivity需要繼承BackHandleInterface椿每,子Fragment會(huì)通過(guò)該接口告訴宿主Activity自己是當(dāng)前屏幕可見(jiàn)的Fragment
public interface BackHandledInterface {
public abstract void setSelectedFragment(BackHandledFragment selectedFragment);
}
public class MainActivity extends FragmentActivity implements BackHandledInterface{
private BackHandledFragment mBackHandedFragment;
private boolean hadIntercept;
@Override
public void setSelectedFragment(BackHandledFragment selectedFragment) {
this.mBackHandedFragment = selectedFragment;
}
@Override
public void onBackPressed() {
if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){
if(getSupportFragmentManager().getBackStackEntryCount() == 0){
super.onBackPressed();
}else{
getSupportFragmentManager().popBackStack();
}
}
}
}
總結(jié)一下:
每個(gè)Fragment的onCreate方法中,會(huì)判斷宿主Activity是否實(shí)現(xiàn)了上述3中所說(shuō)的接口英遭,在Fragment的onStart方法中间护,通過(guò)Fragment 獲取Activity 引用,然后調(diào)用該Activity實(shí)現(xiàn)的接口方法告知宿主FragmentActivity自己是當(dāng)前屏幕可見(jiàn)的Fragment,宿主Activity就可以在onBackPressed 方法中對(duì)Back事件進(jìn)行判斷處理了