转载请注明出处:http://write.blog.csdn.net/postedit/40507387

Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能。假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentActivity。当然,我们可以将每个Fragment对应的Transaction放到BackStack中,但是如果每个Fragment有对返回事件的特殊消费,那么在FragmentActivity的onBackPressed()中的代码就会比较混乱,例如:

  1. @Override
  2. public void onBackPressed() {
  3. if(selectedFragment.equals(fragmentA) && fragmentA.hasExpandedRow()) {
  4. fragmentA.collapseRow();
  5. } else if(selectedFragment.equals(fragmentA) && fragmentA.isShowingLoginView()) {
  6. fragmentA.hideLoginView();
  7. } else if(selectedFragment.equals(fragmentA)) {
  8. popBackStack();
  9. } else if(selectedFragment.equals(fragmentB) && fragmentB.hasCondition1()) {
  10. fragmentB.reverseCondition1();
  11. } else if(selectedFragment.equals(fragmentB) && fragmentB.hasCondition2()) {
  12. fragmentB.reverseCondition2();
  13. } else if(selectedFragment.equals(fragmentB)) {
  14. popBackStack();
  15. } else {
  16. // handle by activity
  17. super.onBackPressed();
  18. }
  19. }

这对于有代码洁癖的程序猿显然是不能容忍的,后来发现了一种优雅的解决方案。

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

  1. public abstract class BackHandledFragment extends Fragment {
  2. protected BackHandledInterface mBackHandledInterface;
  3. /**
  4. * 所有继承BackHandledFragment的子类都将在这个方法中实现物理Back键按下后的逻辑
  5. * FragmentActivity捕捉到物理返回键点击事件后会首先询问Fragment是否消费该事件
  6. * 如果没有Fragment消息时FragmentActivity自己才会消费该事件
  7. */
  8. protected abstract boolean onBackPressed();
  9. @Override
  10. public void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. if(!(getActivity() instanceof BackHandledInterface)){
  13. throw new ClassCastException("Hosting Activity must implement BackHandledInterface");
  14. }else{
  15. this.mBackHandledInterface = (BackHandledInterface)getActivity();
  16. }
  17. }
  18. @Override
  19. public void onStart() {
  20. super.onStart();
  21. //告诉FragmentActivity,当前Fragment在栈顶
  22. mBackHandledInterface.setSelectedFragment(this);
  23. }
  24. }

宿主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. private BackHandledFragment mBackHandedFragment;
  3. private boolean hadIntercept;
  4. @Override
  5. public void setSelectedFragment(BackHandledFragment selectedFragment) {
  6. this.mBackHandedFragment = selectedFragment;
  7. }
  8. @Override
  9. public void onBackPressed() {
  10. if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){
  11. if(getSupportFragmentManager().getBackStackEntryCount() == 0){
  12. super.onBackPressed();
  13. }else{
  14. getSupportFragmentManager().popBackStack();
  15. }
  16. }
  17. }
  18. }

优雅的让Fragment监听返回键的更多相关文章

  1. Android 优雅的让Fragment监听返回键

    Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentAc ...

  2. Android必知必会-Fragment监听返回键事件

    如果移动端访问不佳,请尝试 Github版<–点击左侧 背景 项目要求用户注册成功后进入修改个人资料的页面,且不允许返回到上一个页面,资料修改完成后结束当前页面,进入APP主页. 由于是使用多个 ...

  3. 让Fragment监听返回键

    Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.所以使用到了以下的方法. 首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPre ...

  4. Fragment监听返回键

    首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对 ...

  5. Android监听返回键、Home键+再按一次返回键退出应用

    Android监听返回键需重写onKeyDown()方法 Home键keyCode==KeyEvent.KEYCODE_HOME @Override public boolean onKeyDown( ...

  6. Android 如何监听返回键,弹出一个退出对话框

    android 如何监听返回键点击事件,并创建一个退出对话框, 防止自己写的应用程序不小心点击退出键而直接退出.自己记录下这个简单的demo,备用. public class BackKeyTest ...

  7. android 监听返回键

    android监听返回键 public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE ...

  8. 【Android】Android实现监听返回键,主键(HOME),菜单键

    目录结构: contents structure [+] 简介 监听 返回键 监听 主键(Home键) 监听 菜单键 一.简介 本篇文章介绍如何在Android中实现监听返回键,主键,菜单键.一般情况 ...

  9. Android 监听返回键退出程序的两种实现

    1.Android 双击返回键退出程序 思路:用户按下返回键时设定一个定时器来监控是否2秒内实现了退出,如果用户没有接着按返回键,则清除第一次按返回键的效果,使程序还原到第一次按下返回键之前的状态.定 ...

随机推荐

  1. Tomcat 的 SSL 配置

    本教程使用 JDK 6 和 Tomcat 7,其他版本类似. 基本步骤: 使用 java 创建一个 keystore 文件 配置 Tomcat 以使用该 keystore 文件 测试 配置应用以便使用 ...

  2. Plain old data structure(POD)

    Plain old data structure, 缩写为POD, 是C++语言的标准中定义的一类数据结构,POD适用于需要明确的数据底层操作的系统中.POD通常被用在系统的边界处,即指不同系统之间只 ...

  3. favicon.ico显示,favicon显示,favicon图标显示

    favicon.ico显示,favicon显示,favicon图标显示 >>>>>>>>>>>>>>>> ...

  4. 推断类型var

    1.为什么使用推断类型var var可以根据变量的初始值自动推断局部变量类型,当无法确定所用变量的具体类型时可使用var 2.如何使用推断类型var 客户端代码 static void Main(st ...

  5. VM的Linux CentOS系统的VMTools的手动安装

    VM的Linux CentOS系统的VMTools的手动安装 一是没时间安装,另外是一直用的是VM的绿色版,里面没有Linux.iso 文件 今天晚上安装上了 linux 的vmtools ,再也不用 ...

  6. 苹果手机 iframe 无法滚动bug

    原来在html5下,iframe 只有 src 属性scroling='no' 解决办法:在iframe外加一层第div,设置样式-webkit-overflow-scrolling:touch;ov ...

  7. (转)Spring读书笔记-----使用Spring容器(二)

    一.使用ApplicationContext 前面介绍了,我们一般不会使用BeanFactory实例作为Spring容器,而是使用ApplicationContext实例作为容器,它增强了BeanFa ...

  8. 多线程、Socket

      多线程 线程.进程和应用程序域 进程:进程是一个操作系统上的概念,用来实现多任务并发执行,是资源分配的最小单元,各个进程是相互独立的,可以理解为执行当中的程序,在操作系统中一般用一个称为PCB的结 ...

  9. c++ 中关于int,unsigned int , short的关系与应用

    转载:http://www.cppblog.com/xyjzsh/archive/2010/10/20/130554.aspx?opt=admin   int类型比较特殊,具体的字节数同机器字长和编译 ...

  10. Mac Zip命令

    mac终端命令 zip -[parameter] [yourName].zip someFileOrDiectory -q 表示不显示压缩进度状态 -r 表示子目录子文件全部压缩为zip //这部比较 ...