重写FragmentTabHost,避免导航栏切换过程中再次创建内容页面Fragment
来源:互联网 发布:android安装 mysql 编辑:程序博客网 时间:2024/05/17 00:58
问题描述: 上一篇文章我们在导航栏对应的每个Fragment的onActivityCreated(…)方法中打印一个toast,在反复切换页面页面时,都显示了toast对话框。这说明,切换的时候,每个内容页面fragment再次重新创建了。预期是,第一次进入创建,随后切换进入不再创建。
解决方案: 如果之前使用radioGroup+FrameLayout实现导航栏的,想必当时也遇到过上述情况,当时我的解决思想是。新建内容页面fragment时,我就把它保存起来,给它一个标记(tag),下次再切换到这个页面时,通过这个tag字段搜索一下是否已经创建,如果已经创建就直接拿出来并显示,没有则创建并添加tag。其实,重写FragmentTabHost实现的思想也是如此,因为FragmentTabHost+FrameLayout的实现原理和radioGroup+FrameLayout的差不多。下面看FragmentTabHost的一个方法,此方法是解决问题的关键,代码如下:
private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) { TabInfo newTab = null; for (int i=0; i<mTabs.size(); i++) { TabInfo tab = mTabs.get(i); if (tab.tag.equals(tabId)) { newTab = tab; } } if (newTab == null) { throw new IllegalStateException("No tab known for tag " + tabId); } if (mLastTab != newTab) { if (ft == null) { ft = mFragmentManager.beginTransaction(); } if (mLastTab != null) { if (mLastTab.fragment != null) { ft.detach(mLastTab.fragment); } } if (newTab != null) { if (newTab.fragment == null) { newTab.fragment = Fragment.instantiate(mContext, newTab.clss.getName(), newTab.args); ft.add(mContainerId, newTab.fragment, newTab.tag); } else { ft.attach(newTab.fragment); } } mLastTab = newTab; } return ft; }
重点看ft.detach(mLastTab.fragment)和ft.attach(newTab.fragment),先来解释几个FragmentTransaction的方法:
(1)attach(Fragment fragment)方法, 主要意思是:如果之前的Fragment通过detach(Fragment fragment)从UI分离,则会重新创建并显示。
(2)detach(Fragment fragment) 主要意思是:从UI分离(就是被切换了),就会从UI中移除,进而销毁。
(3)hide(Fragment fragment) 主要意思:隐藏Fragment,不销毁。
(4)show(Fragment fragment) 主要意思:显示隐藏的Fragment。
看了上面的四个方法后,结合doTabChanged()的内容应该可以明白,什么FragmentTabHost在切换时重新创建了Fragment。主要原因就是使用了ft.detach(mLastTab.fragment)和ft.attach(newTab.fragment)。如果我们把这两个方法用hide和show替换掉,这样就可以解决问题了。操作流程,把android.support.v4.app包下的FragmentTabHost拷贝到我们自定义控件的文件夹下,例如:我放到我项目的widget文件夹下,然后修改doTabChanged()方法。修改代码如下:
private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) { TabInfo newTab = null; for (int i=0; i<mTabs.size(); i++) { TabInfo tab = mTabs.get(i); if (tab.tag.equals(tabId)) { newTab = tab; } } if (newTab == null) { throw new IllegalStateException("No tab known for tag " + tabId); } if (mLastTab != newTab) { if (ft == null) { ft = mFragmentManager.beginTransaction(); } if (mLastTab != null) { if (mLastTab.fragment != null) { // 将detach替换为hide,隐藏Fragment // ft.detach(mLastTab.fragment); ft.hide(mLastTab.fragment); } } if (newTab != null) { if (newTab.fragment == null) { newTab.fragment = Fragment.instantiate(mContext, newTab.clss.getName(), newTab.args); ft.add(mContainerId, newTab.fragment, newTab.tag); } else { // 将attach替换为show,显示Fragment // ft.attach(newTab.fragment); ft.show(newTab.fragment); } } mLastTab = newTab; } return ft; }
最后, 把布局中使用的android.support.v4.app.FragmentTabHost改为自己重写的FragmentTabHost。例如我的修改为com.lyl.weeklearning.widget.FragmentTabHost。还有在使用FragmentTabHost的java文件中,修改导入包,例如我的修改为:import com.lyl.weeklearning.widget.FragmentTabHost; 到此,文章结束了,有写的不对的地方,欢迎评论指正^_^
- 重写FragmentTabHost,避免导航栏切换过程中再次创建内容页面Fragment
- FragmentTabHost切换Fragment时避免重复加载UI,导致切换后重绘页面的问题解决
- 重写FragmentTabHost,防止FragmentTabHost切换fragment重新调用onCreateView()
- 底部导航栏:FragmentTabHost+Fragment
- 用FragmentTabHost管理Fragment,实现页面切换
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载view
- FragmentTabHost切换Fragment时避免UI重新加载
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免重复加载UI
- FragmentTabHost切换Fragment时避免UI重新加载
- 遍历文件夹输出版本信息
- ECMAScript6入门简述&索引篇(摘自阮一峰的《ECMAScript 6 入门》)
- android图片上传springMvc
- 自定义手机号码分割样式"188 8888 8888"的EditText
- 实力打脸!2017大量热门行业等着程序员,谁还敢黑程序员?
- 重写FragmentTabHost,避免导航栏切换过程中再次创建内容页面Fragment
- SpringMVC拦截器
- “空”的艺术-当数据为空时显示什么
- mysql5.7.1.16出现[Err] 1146
- TensorFlow学习(一)入门
- jsp中<jsp:forward page=""/>和response.sendRedirect("")两种跳转的区别
- 计算机视觉之跟踪算法——CamShift跟踪算法
- 问题 A: 那些年我们一起考过的浙大
- 使用IntelliJ IDEA开发SpringMVC网站(一)开发环境