由 transaction.addtoBackStack 不正常工作引出 v4,v7 包与默认包混用的问题

一、现象

如下,是一段普通的替换 Fragment 的代码:

AnotherRightFragment fragment = new AnotherRightFragment();
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.right_layout, fragment);
                transaction.commit();

一般情况下,我们在按返回键时,会结束当前 Activity,如果我们通过如下代码替换 Fragment,则可以将替换的 Fragment 添加至返回栈,这时按返回键会先将 Fragment 出栈,然后再将 Activity 出栈。

AnotherRightFragment fragment = new AnotherRightFragment();
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.right_layout, fragment);
                transaction.addToBackStack(null);
                transaction.commit();

很明显,我们只添加了一行transaction.addToBackStack(null);就能实现,然而在我使用的时候,它愣是不起作用,这是为什么呢。

二、原理

其实很简单,因为我的 Activity 继承了 v7 包中的 ActionBarActivity,而 Fragment 使用的却是 app 包下的类。相信大家在开发的过程中应该经常遇到类似的问题,比如初学者常犯的一个错误,在 ActionBarActivity 中调用getActionBar()方法获取 ActionBar 得到的却是一个 null,实际上在 ActionBarActivity 正确的获取 ActionBar 的方法是getSupportActionBar()

三、解决方案

support 包下的 v4,v7,v13 包中的类,不可与 app 等包下的类混用,如果用 v7 包下的 ActionBarActivity,那么你就必须用 v4 包下的 Fragment,如果用 app 包下的 Activity,那么你就必须用 app 包下的 Fragment。那么如何避免混用呢,很简单,在你使用如 Fragment 这种类的时候,肯定需要 import 这个类,因为有多个 Fragment 类,你就会有多个选项,只需要注意与你之前使用的统一即可。此外,良好的编码习惯和更多的经验也会让你少犯这种错误。