当前位置: 代码迷 >> Android >> Android - Handling back button press Inside Fragments
  详细解决方案

Android - Handling back button press Inside Fragments

热度:178   发布时间:2016-04-28 01:10:35.0
Android -- Handling back button press Inside Fragments

干货(1)

首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对Back事件的消费逻辑。onBackPressed返回布尔值,宿主FragmentActivity将会根据该方法的返回值判断子Fragment是否有消费Back事件。此外,宿主FragmentActivity还会保持一份当前Fragment的引用,当用户按下Back键时,宿主Activity会判断当前Fragment是否需要消费该事件,如果没有Fragment消费才会自己消费。

public abstract class BackHandledFragment extends Fragment {        protected BackHandledInterface mBackHandledInterface;            /**      * 所有继承BackHandledFragment的子类都将在这个方法中实现物理Back键按下后的逻辑      * FragmentActivity捕捉到物理返回键点击事件后会首先询问Fragment是否消费该事件      * 如果没有Fragment消息时FragmentActivity自己才会消费该事件      */      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,当前Fragment在栈顶          mBackHandledInterface.setSelectedFragment(this);      }        }

宿主FragmentActivity需要继承BackHandledIntegerface,子Fragment会通过该接口告诉宿主FragmentActivity自己是当前屏幕可见的Fragment。

public interface BackHandledInterface {      public abstract void setSelectedFragment(BackHandledFragment selectedFragment);  }

所以在Fragment的onCreate中会判断宿主FragmentActivity是否已继承了该接口。在Fragment的onStart()方法中就会调用该接口告诉宿主FragmentActivity自己是当前屏幕可见的Fragment。
宿主FragmentActivity就可以在onBackPressed()方法中对Back事件进行判断处理了。

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();              }          }      }  }

干货(2)

在Fragment的onResume中通过View去监听。(要注意setFocusableInTouchMode()和requestFocus())

@Overridepublic void onResume() {    super.onResume();    getView().setFocusableInTouchMode(true);    getView().requestFocus();    getView().setOnKeyListener(new View.OnKeyListener() {        @Override        public boolean onKey(View v, int keyCode, KeyEvent event) {            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){                // handle back button                return true;            }            return false;        }    });}

我是天王盖地虎的分割线

 

 

 

参考:http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/

http://stackoverflow.com/questions/22552958/handling-back-press-when-using-fragments-in-android

  相关解决方案