zoukankan      html  css  js  c++  java
  • 用Fragment制作的Tab页面产生的UI重叠问题

    本文出处: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博主亲测,没有什么卵用。

  • 相关阅读:
    iOS之内存管理(ARC)
    分布式锁1 Java常用技术方案
    谈谈如何使用Netty开发实现高性能的RPC服务器
    前后端分离开发模式下后端质量的保证 —— 单元测试
    jquery实现"跳到底部","回到顶部"效果
    html内容超出了div的宽度如何换行让内容自动换行
    采用easyui+ajax+htm+ashx编写 通过用户对应角色 角色对应菜单 控制用户的访问权限
    javascript [] 与 {} 的区别
    图说设计模式
    T4教程1 T4模版引擎之基础入门
  • 原文地址:https://www.cnblogs.com/a446276468/p/5354206.html
Copyright © 2011-2022 走看看