用Fragment制作的Tab页面产生的UI重叠问题
2016-04-05 11:01
323 查看
本文出处: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,因此不会有重叠现象。
-------------------------------------华丽的分割线------------------------------------------
以下参考: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博主亲测,没有什么卵用。
在用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博主亲测,没有什么卵用。
相关文章推荐
- Xamarin.Android之UI Test简单入门
- 传感器,加速计,蓝牙以及UIDevice方法的详细说明
- 【poj 3368 】 Frequent values 线段树应用
- Kendo UI常用示例汇总(四)
- 【poj 3368】Frequent values 题意&题解&代码(C++)
- 你真的会用UITableView嘛
- N_queen
- Fedora修复grub2启动项grub rescue
- weblogic Server Failed To Start Due To Error BEA-320142
- 使用EasyUi实现三级联动
- Android延时启动效果+轮播图+点击进入+沉浸式状态栏+按钮点击颜色渐变效果+好看的UI框架
- UITableViewCell 复杂时,高度计算优
- android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
- ios 通过设置UI控件的center和size来设置位置时需注意!
- easyUI
- iOS--xcodebuild命令记录
- 用require加载js
- The working copy is locked due to a previous error
- AndroidUI组件之AdapterViewFilpper
- DockPanelSuite中的DocumentStyle