Activty能够直接响应返回键,而Fragment却不行,可用以下方式:ide
建立一个抽象类BackHandledFragment,该类中有一个抽象方法onBackPress(),全部BackHandledFragment的子类在onBackPress()中处理各自对Back事件的响应逻辑。onBackPress()返回boolean值,宿主FragmentActivity将会根据该方法的返回值判断子Fragment是否有消费Back事件。此外,宿主FragmentActivity还会保持一份当前Fragment的引用,当用户按下Back键时,宿主Activity会判断当前Fragment是否须要消费改时间,若是没有Fragment消费才会本身消费。this
/** * Fragment响应返回键 * @author Administrator * */ public abstract class BackHandledFragment extends Fragment{ protected BackHandledInterface mBackHandledInterface; public 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,当前Fragment在栈顶 mBackHandledInterface.setSelectedFragment(this); } }
宿主FragmentActivity需实现BackHandledIntegerface,子Fragment会经过该接口告诉宿主FragmentActivity本身是当前屏幕可见的Fragment.spa
public interface BackHandledInterface { public abstract void setSelectedFragment(BackHandledFragment selectedFragment); }
因此在Fragment的onCreate()中会判断宿主FragmentActivity是否已实现了该接口。在Fragment的onStart()方法中就会调用该接口告诉宿主Fragment本身是当前屏幕可见的Fragment。code
宿主FragmentActivity就能够在onBackPressed()方法中对Back时间进行判断处理了。blog
public class MainActivity extends FragmentActivity implements BackHandledInterface{ private BackHandledFragment mBackHandedFragment; private boolean hadIntercept; private Button mBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.mBtn = (Button)findViewById(R.id.btn); this.mBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { MyFragment f = new MyFragment(); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.container, f); ft.addToBackStack("tag"); ft.commit(); } }); } @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(); } } } }
在Fragment中的使用接口
public class MyFragment extends BackHandledFragment { private boolean hadIntercept; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return getLayoutInflater(savedInstanceState).inflate(R.layout.fragment_a, null); } @Override protected boolean onBackPressed() { if(hadIntercept){ return false; }else{ Toast.makeText(getActivity(), "Click MyFragment", Toast.LENGTH_SHORT).show(); hadIntercept = true; return true; } } }