转载请注明出处: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. Mysql解压版的安装

    Mysql解压版的安装 ——@梁WP 1.解压mysql到合适的地方 2.右击计算机-属性-高级系统设置-高级-环境变量,弹出“环境变量”对话框,修改下面的系统变量 3.新建MYSQL_HOME变量, ...

  2. sendkeys && appactivate

    sendkeys    用于输入键盘按键 appactivate 用于聚焦程序 on error resume next set ws = createObject("wscript.she ...

  3. U3D 抛物线的方法

    本文转载:http://www.manew.com/thread-44642-1-1.html 无论是愤怒的小鸟,还是弓箭发射功能,亦或者模拟炮弹受重力影响等抛物线轨迹,都可以使用本文的方法,模拟绝对 ...

  4. 一个操作Sql2005数据库的类(备份,还原,分离,附加,添加删除用户等操作)(转载)

    /* * 更新时间 :2011-09-01 16:06 * 更 新 人 :苏飞 */ using System; using System.Collections.Generic; using Sys ...

  5. Windows下的多线程

    Windows下的进程和Linux下的进程是不一样的,它比较懒惰,从来不执行任何东西,它只是为线程提供执行环境,然后由线程负责执行包含在进程的地址空间中的代码.当创建一个进程的时候,操作系统会自动创建 ...

  6. 如何使用event 10049分析定位library cache lock and library cache pin

    Oracle Library Cache 的 lock 与 pin 说明 一. 相关的基本概念 之前整理了一篇blog,讲了Library Cache 的机制,参考: Oracle Library c ...

  7. JAVA zip解压 MALFORMED 错误

    最近在在使用zip 解压时,使用JDK1.7及以上版本在解压时,某些文件会报异常 Exception in thread "main" java.lang.IllegalArgum ...

  8. html-----002

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. linux命令sed学习笔记

    sed其实就是两个主要的知识点,那就是“怎么选择”和“怎么操作”!

  10. php redis 【摘自网上,只为参考】

    ubuntu下安装php redis sudo apt-get install redis-server 测试redis是否安装成功:注意:要开启redis redis-cliset test hel ...