Android项目开发填坑记-Fragment的onBackPressed

  • Github版
  • CSDN版

知识背景

Fragment在当前的Android开发中,有两种引用方式,一个是 Android 3.0 时加入的,一个是supportV4包中的。这里简称为Fragment3.0FragmentV4

Fragment中的返回

在Fragment中经常用到自定义标题栏,而返回按钮的点击事件一般设置为:getActivity().onBackPressed();,这样可以使得点击返回按钮和点击手机上的返回键的效果一致,即调用所在Activity的onBackPressed();

那么可能会造成一个问题:

本来你是想点击返回按钮让当前的Fragment出栈,显示上一个Fragment,但是却关闭了整个Fragment所在的Activity

即 启动Activity–>显示FragmentA–>显示FragmentB–>用户点击返回按钮或者手机上的返回键–>退出了Activity。

原因

下面我们追踪一下代码调用,找找产生这种现象的原因:

Fragment 3.0getActivity().onBackPressed()

Activity类

public void onBackPressed() {
        if (mActionBar != null && mActionBar.collapseActionView()) {
            return;
        }

        if (!mFragments.getFragmentManager().popBackStackImmediate()) {
            finishAfterTransition();
        }
    }

Fragment V4getActivity().onBackPressed()

FragmentActivity

public void onBackPressed() {
        if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) {
            supportFinishAfterTransition();
        }
    }

真相

从对代码调用的追踪,发现了真相。Fragment3.0FragmentV4

  1. Fragment3.0getActivity().onBackPressed()默认调用了ActivityonBackPressed()方法,方法里面使用的getFragmentManager()获取FragmentManager对象弹出栈内的Fragment3.0版的Fragment
  2. FragmentV4getActivity().onBackPressed()默认调用了FragmentActivityonBackPressed()方法,方法里面使用的getSupportFragmentManager()获取FragmentManager对象进行弹出栈内的FragmentV4版的Fragment

简单说就是Fragment3.0要放在继承了Activity的Activity中使用:

public class XXX_Activity extends Activity{
...
}

FragmentV4要放在继承了FragmentActivity的Activity中使用:

public class XXX_Activity extends FragmentActivity{
...
}

//或者系统默认的 FragmentActivity 的子类 AppCompatActivity
public class XXX_Activity extends AppCompatActivity{
...
}

Fragment和Activity版本不匹配时

开发的时候,或许并不能达到Fragment版本和对应的Activity相匹配的理想状态,那么就有了下面的一个比较完善的解决方案:

解决方案:

使用其匹配的Activity类的onBackPressed()方法的代码重写所在的ActivityonBackPressed()方法:

FragmentV4配合继承了Activity的Activity中时:

XXX_Activity extends Activity

//使用FragmentActivity的onBackPressed()的代码覆盖
@Override
public void onBackPressed() {
        if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) {
            supportFinishAfterTransition();
        }
    }

Fragment3.0配合继承了FragmentActivity的Activity中时:

XXX_Activity extends FragmentActivity(或者AppCompatActivity)

//使用Activity的onBackPressed()的代码覆盖
@Override
public void onBackPressed() {
        if (mActionBar!=null&&mActionBar.collapseActionView()) {
            return;
        }

        if (!mFragments.getFragmentManager().popBackStackImmediate()) {
            finishAfterTransition();
        }
    }

总结

由于当前 Android Studio 默认新建的 Activity 继承于 AppCompatActivity,所以建议大家使用FragmentV4进行开发,这样能省下不少麻烦,本系列还有一篇文章介绍Fragment3.0使用onAttach时的Bug,而这个对于FragmentV4则没有。
传送门:Android项目开发填坑记-Fragmen的onAttach方法

PS:

你可以关注的我Github、CSDN和微博

你可能感兴趣的:(android)