本文出处:http://blog.csdn.net/twilight041132/article/details/43812745

在用Fragment做Tab页面,发现有时候进入应用会同时显示多个Tab内容,UI发生重叠。

当应用被强行关闭后(通过手机管家软件手动强关,或系统为节省内存自动关闭应用),再次进入应用时,每次都有这现象。

第一次进入应用时,根据选择的tab分别创建对应的Fragment,之后每次选择页面时隐藏其他tab内容。

通过分析发现,正常back键退出应用时,Activity及Fragment对象会被销毁,因此再次进入时会在切换到Tab时创建对应的Fragment对象。

但是当强行关闭应用后,Activity虽然被回收,但Fragment对象仍然保持,再次进入应用时,系统会分别调用Fragment的onAttach方法将其附加到Activity上,

02-08 12:41:24.107: D/FragmentTab1(7032): onAttach

02-08 12:41:24.107: D/FragmentTab3(7032): onAttach

这里对应的就是强行关闭应用前的fragment对象,

后面会分别调用两个fragment的onCreateView方法,因此这两个Fragment对应的View层次结构都会加到Activity的View层次中。

虽然setSelection方法会把所有fragment先隐藏再显示选中的对象,但由于此时Activity中Fragment对象的成员变量还未初始化,因此会再次实例化fragment对象,

之后add、show及hide的都是在第二次创建的对象上操作的,而之前被保持的fragment对象的视图层次已经反映到Activity视图中并且不会被hide,因此发生了上述重叠现象。

解决方法:

在Activity的onAttachFragment方法中,有一个fragment参数,它就是onAttach方法对应的Fragment对象,

通过判断这个fragment对象,如果属于我们的FragmentTabX类并且该类还未被实例化过,则将Activity的成员变量mFragmentTabX指向该fragment对象,这样就可以在原来的fragment对象上操作add/show/hide,因此不会有重叠现象。

@Override
public void onAttachFragment(Fragment fragment) {
// TODO Auto-generated method stub
super.onAttachFragment(fragment);
Log.d(TAG,"onAttachFragment");
//mTab1,mTab2,mTab3 是在Activity中创建的Fragment
if (mTab1 == null && fragment instanceof FragmentTab1) {
mTab1 = (FragmentTab1)fragment;
}else if (mTab2 == null && fragment instanceof FragmentTab2) {
mTab2 = (FragmentTab2)fragment;
}else if (mTab3 == null && fragment instanceof FragmentTab3) {
mTab3 = (FragmentTab3)fragment;
}
}

-------------------------------------华丽的分割线------------------------------------------

以下参考:http://m.blog.csdn.net/article/details?id=41912445

上面的貌似说的很有道理,但是测试了一下还是不行,也许是我遇到的问题跟他说的不一致。

我遇到的问题是:当报错时(比如空指针)主页面出现Fragment重叠。

在debug的时候,发现CarFragment是执行了onCreateView()的,意味着成功生成了车辆管理的界面,但究竟为什么仍然显示的是SupplyFragment的界面呢,直观感觉,SupplyFragment像一层蒙板一样放在最上层,点击其他4个tab栏,生成的Fragment都被隐藏在了它的下面。

后来在google查到相关资料,原因是:当Fragment长久不使用,系统进行回收,FragmentActivity调用onSaveInstanceState保存Fragment对象。很长时间后,再次打开app,系统恢复保存的Fragment,但是在FragmentActivity重新执行生命周期的时候,我们重新生成了fragment对象附加到该FragmentActivity,系统恢复的fragment和FragmentActivity失去关联,进而出错。

解决方案为以下两种:

方法1:在fragmentActivity里oncreate方法判断savedInstanceState==null才生成新Fragment,否则不做处理。

方法2:在fragmentActivity里重写onSaveInstanceState方法,但不做实现,也就是将super.onSaveInstanceState(outState)注释掉。

方法2很好理解,当系统要回收Fragment时,我们告诉系统:不要再保存Fragment。相当于用户回到app的时候,我们就当用户是第一次打开app(因为很长时间没有操作了)。

方法1理论上没有问题,但在测试的时候,用了一种非常规的方案,横竖屏切换来测试,而在横竖屏切换时,系统会首先销毁FragmentActivity再重新生成,无法模拟测试条件,还要再研究。

方法1博主亲测,没有什么卵用。

最新文章

  1. javascript除法如何取整
  2. android NDK入门 windows下安装cygwin
  3. arcgis server账号需要设置地图缓存的访问权限
  4. nginx-upload-module模块实现文件断点续传
  5. Decoder with 3 Inputs and 2 3 = 8 Outputs
  6. lvs keepalived 安装配置详解
  7. 1.2CPU和GPU的设计区别
  8. 文本输入框的两种div+css的写法
  9. PPTPD服务端搭建
  10. 【VB超简单入门】六、基本数据类型
  11. c++ static用法总结【转载】
  12. c# textbox的滚动条总是指向最底端
  13. iis部署python运行环境
  14. 使用Java可以做得一些事
  15. QT中资源文件的使用
  16. 配置jboss为windows服务
  17. python中的魔法参数:*args和**kwargs
  18. python base64加密文本内容(1)
  19. tcp/ip 3次握手和4次挥手
  20. Window python下载安装

热门文章

  1. onmouseover和onmouseout的那些事
  2. xcode 打静态库.a文件
  3. 微信订阅号里实现oauth授权登录,并获取用户信息 (完整篇)
  4. 转载自@机智的新手:使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
  5. bash操作小结
  6. django(五)
  7. python数据类型及其常用方法
  8. thinkphp关联模型的注意大小写
  9. jquery的.submit
  10. java获取当前执行文件的路径