标签:
Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能。所以使用到了以下的方法。
首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对Back事件的消费逻辑。onBackPressed返回布尔值,宿主FragmentActivity将会根据该方法的返回值判断子Fragment是否有消费Back事件。此外,宿主FragmentActivity还会保持一份当前Fragment的引用,当用户按下Back键时,宿主Activity会判断当前Fragment是否需要消费该事件,如果没有Fragment消费才会自己消费。
1 public abstract class BackHandledFragment extends Fragment {
3 protected BackHandledInterface mBackHandledInterface;
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 // instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例
16 if(!(getActivity() instanceof BackHandledInterface)){
17 throw new ClassCastException("Hosting Activity must implement BackHandledInterface");
18 }else{
19 this.mBackHandledInterface = (BackHandledInterface)getActivity();
20 }
21 }
22
23 @Override
24 public void onStart() {
25 super.onStart();
26 //告诉FragmentActivity,当前Fragment在栈顶
27 mBackHandledInterface.setSelectedFragment(this);
28 }
29
30 }
宿主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{
3 private BackHandledFragment mBackHandedFragment;
4 private boolean hadIntercept;
6 private Button mBtn;
7
8 @Override
9 protected void onCreate(Bundle savedInstanceState) {
10 super.onCreate(savedInstanceState);
11 setContentView(R.layout.activity_main);
12 this.mBtn = (Button)findViewById(R.id.btn);
13 this.mBtn.setOnClickListener(new OnClickListener() {
14
15 @Override
16 public void onClick(View v) {
17 MyFragment f = new MyFragment();
18 FragmentManager fm = getSupportFragmentManager();
19 FragmentTransaction ft = fm.beginTransaction();
20 ft.replace(R.id.container, f);
21 ft.addToBackStack("tag");
22 ft.commit();
23 }
24 });
25 }
26
27 @Override
28 public void setSelectedFragment(BackHandledFragment selectedFragment) {
29 this.mBackHandedFragment = selectedFragment;
30 }
31
32 @Override
33 public void onBackPressed() {
34 if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){
35 if(getSupportFragmentManager().getBackStackEntryCount() == 0){
36 super.onBackPressed();
37 }else{
38 getSupportFragmentManager().popBackStack();
39 }
40 }
41 }
42 }
在Fragment中调用使用。
1 public class MyFragment extends BackHandledFragment {
3 private boolean hadIntercept;
5 @Override
6 public View onCreateView(LayoutInflater inflater,
7 @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
8 return getLayoutInflater(savedInstanceState).inflate(R.layout.fragment_a, null);
9 }
10
11 @Override
12 protected boolean onBackPressed() {
13 if(hadIntercept){
14 return false;
15 }else{
16 Toast.makeText(getActivity(), "Click MyFragment", Toast.LENGTH_SHORT).show();
17 hadIntercept = true;
18 return true;
19 }
20 }
21
22 }
Demo:https://github.com/mxy1228/FragmentHandleBackDemo/
标签:
原文地址:http://www.cnblogs.com/androidsj/p/4576879.html