android 控件 fragment 切换优化 混乱
来源:互联网 发布:linux编译工具链 编辑:程序博客网 时间:2024/04/26 11:55
在项目中需要进行Fragment的切换,一直都是用replace()方法来替换Fragment:然后总感觉切换的时候有些卡顿,原来的代码
/** * 切换页面,这里采用回调 * */ public void switchFragment(Fragment f) { if (f == null) return; FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction(); transaction.replace(R.id.fl_main, f); // transaction.addToBackStack(descString); transaction.commit(); // 让menu回去 menu.toggle(); }
但是,这样会有一个问题:
每次切换的时候,Fragment都会重新实例化,重新加载一边数据,这样非常消耗性能和用户的数据流量。
就想,如何让多个Fragment彼此切换时不重新实例化?
翻看了Android官方Doc,和一些组件的源代码,发现,replace()这个方法只是在上一个Fragment不再需要时采用的简便方法。
正确的切换方式是add(),切换时hide(),add()另一个Fragment;再次切换时,只需hide()当前,show()另一个。
这样就能做到多个Fragment切换不重新实例化
/** * 切换页面的重载,优化了fragment的切换 * * @param f * @param descString */ public void switchFragment(Fragment from, Fragment to) { if (from == null || to == null) return; FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction().setCustomAnimations(R.anim.tran_pre_in, R.anim.tran_pre_out); if (!to.isAdded()) { // 隐藏当前的fragment,add下一个到Activity中 transaction.hide(from).add(R.id.fl_main, to).commit(); } else { // 隐藏当前的fragment,显示下一个 transaction.hide(from).show(to).commit(); } // 让menu回去 menu.toggle(); }
实用代码
private void setTabSelection(int index) {//获得事务FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();hideFragment(fragmentTransaction);//把所有的fragment都隐藏changeNormal();//把导航栏全部设置为 未选switch (index) {case 0:imgBtn[0].setImageResource(imgChecked[0]);txtBtn[0].setTextColor(getResources().getColor(R.color.top_color));//设置为被选(文字,图片)HomeFragment hotSellFragment = (HomeFragment) fragmentManager.findFragmentByTag("one");if (hotSellFragment == null) {fragmentTransaction.add(container, new HomeFragment(), "one");//要么添加一个在栈的最上面} else {fragmentTransaction.show(hotSellFragment);//要么就把隐藏的show显示出来}break;..........................}}//用来隐藏fragmentprivate void hideFragment(FragmentTransaction fragmentTransaction) {HomeFragment hotSellFragment = (HomeFragment) fragmentManager.findFragmentByTag("one");if (hotSellFragment != null) {fragmentTransaction.hide(hotSellFragment);}}//把导航栏的文字和图片都设置为 "灰"private void changeNormal() {for (int i = 0; i < imgBtn.length; i++) {imgBtn[i].setImageResource(imgsNormal[i]);txtBtn[i].setTextColor(getResources().getColor(R.color.gray));}}
混乱
有时候我们推出程序进行操作,或者程序报错的时候,有很大几率会出现fragment重叠的现象。 通过搜集相关资料,我找到了原因,在我切换到其他app的时候,fragment所在activity已经被销毁(这一句话是不是让你恍然大悟,我是这么认为的)。并且通过onSaveInstanceState这个方法保存了相关的数据。
当我再次回到这个app的时候,通过onCreate中的参数savedInstanceState恢复了之前的fragment。此时的FragmentTransaction中的相当于又再次add了fragment进去的,之前保存的fragment也还在。hide()和show()方法对之前保存的fragment已经失效了。所以出现了重叠的现象。 解决方法如下,在进入onCreate函数时,先去判断savedInstanceState是否为null,如果不为null,则表示里面有保存这四个fragment。则不再重新去add这四个fragment,而是通过Tag从前保存的数据中直接去读取。相关代码如下:
public
void
onCreate(Bundle savedInstanceState) {
fManager = getFragmentManager();
if
(savedInstanceState !=
null
) {
allFrg = (AllOfficialAccountFragment) fManager.findFragmentByTag(
"allFrg"
);
movieFrg = (MovieOfficialAccountFragment) fManager.findFragmentByTag(
"movieFrg"
);
newsFrg = (NewsOfficialAccountFragment) fManager.findFragmentByTag(
"newsFrg"
);
otherFrg = (OtherOfficialAccountFragment) fManager.findFragmentByTag(
"otherFrg"
);
}
super
.onCreate(savedInstanceState);
}
另外一个思路是,直接在包含Fragment的Activity中复写
public
void
onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
//Log.v("LH", "onSaveInstanceState"+outState);
//super.onSaveInstanceState(outState); //将这一行注释掉,阻止activity保存fragment的状态
}
0 0
- android 控件 fragment 切换优化 混乱
- Android优化之切换Fragment
- Android开发之多Fragment切换优化
- Android横屏开发的老梗---Fragment切换混乱重叠问题
- Android Fragment加载父控件优化
- Fragment切换优化
- android 控件 fragment 在程序报错,或者清楚缓存的时候 嵌套混乱
- #Android学习#Fragment简单切换及常用控件用法
- Android BottomTabBar控件的使用 Fragment 页面切换
- 对Fragment切换的优化
- 【Fragment精深系列7】Fragment切换优化
- Android 关于fragment切换
- android 首页fragment切换
- Android Fragment切换动画
- Android切换fragment
- android fragment切换
- Android Fragment切换
- android fragment的切换
- 观察者模式抽取的工具类
- 【小镇的技术天梯】lanmp服务器集群搭建(6)rsync+inotify同步主备nfs
- php 发送get,post 请求
- [欧拉函数] BZOJ 2226 [Spoj 5971] LCMSum
- WampServer修改Mysql密码的步骤
- android 控件 fragment 切换优化 混乱
- Spring配置文件中component-scan 扫描指定的包中的类上常用的注解
- ScrollView只能有一个子控件
- 使用框架结构之frameset
- JNI接口函数<一>
- 关于int、short int、long int、long long 的区别
- Android开发:高德地图通过经纬度反编译其位置名称
- 设计模式:代理模式(Proxy)
- Qt之图形(渐变填充)