首页 > 代码库 > FragmentActivity与Fragment一起使用的缓存问题
FragmentActivity与Fragment一起使用的缓存问题
1、背景说明
在界面中,有时候我们会显示如新浪微博底部栏这样的东西,如下图所示。这样的布局结构,我们往往会采用Fragment这种布局去显示,而不会采用Activity去展示,使用Fragment的好处之一,就是我们复用了他的一些组件,其次,这样的界面也是基本等价的,所以我们常用组件替换,这样实现的效果会好于Activity。
给出一个图示说明如下:
当然,现在的新浪微博的底部栏已经不是这样的了,这是我从网上截图过来的一个案例而已。
2、FragmentActivity
在比较老的Android版本上,我们要实现这样的一种底部栏的布局,往往会使用TabHost这样的布局管理器,但是现在已经升级了,我们使用FragmentActivity。
Fragmentactivity 继承自activity,用来解决android3.0 之前没有fragment的api,所以在使用的时候需要导入support包,同时继承FragmentActivity,这样在activity中就能嵌入fragment来实现我们想要的布局效果。
如果我们编译和运行的版本直接大于3.0,你就不需要导入支持包了,可以直接使用这个控件。
3、FragmentManager
FragmentManager是和上面的FragmentActivity配合使用的一个组件,界面中的Fragment由FragmentManager管理,负责传递Activity的生命周期给所管理的Fragment。
在Android3.0以上的版本中,可以直接使用get方法获取FragmentManager对象,即getFragmentManager();在3.0以下的版本中,要使用支持低版本的jar包,可以使用getSupportFragmentManager()这个方法。
4、Fragment
Fragment是我们界面对象的承受者,可以看做是一个独立显示的view对象,不过准确来说他是一个界面控制对象,界面显示还是通过xml文件来显示的。
在上面,我们提到关于Fragment的作用,是用来对一些功能进行重用的,更准确一点的定义是:Fragment主要的作用是用于分离在Activity中的逻辑代码, 让各个独立的Fragment做自己的事, 互不影响. 便于重用。
Fragment主要的适用场景,Activity之间的切换不够流畅,或者是模块化Activity,方便做局部动画效果。
这里给出一段从网上看到的代码,适用于某个ViewGroup内动态添加或替代一个Fragment:
KsMainFragment frg = (KsMainFragment) cls.newInstance(); frg.setArguments(bundle); FragmentTransaction ft = getSupportFragmentManager() .beginTransaction(); ft.replace(R.id.fcon_subview, frg); mFocusFrage = frg; ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit();
类似新浪微博底部栏的形式,会有许多个条目,但是我们不能每次点击一个选项,该选项的数据就加载一次,这样在网络情况不好的时候,用户体验很差,即使是网络很好的情况,也会非常消耗流量,始终是一件不太好的做法。
我们可以参考新浪微博,当我们点击新浪微博底部栏目几个选项的时候,不会出现多次加载的情况(第一次进入首页,在点击个人中心,然后再次回到首页,这个时候第二次进入首页的时候,数据不会再次加载)。如果我们希望更新数据,要么退出了程序再次进入,或者提供下拉刷新、按钮刷新等这样的功能,来更新数据。这样,我们的应用就会比较流畅,体验度更好,用户的流量资源消耗得也更少。
这样的一种缓存方式也是用的空间换时间,但是对于主页面上的四五个界面,现在的手机适用绰绰有余,完全不用担心会出现OOM异常。
6、示例代码
这里给出一段关于缓存的实例代码,这个,额,是本人公司项目中的一段截取,只能给出部分代码,请见谅,但是已经非常完整了,如下:
/** * 主页面 * * @author ljtyzhr * */ public class MainActivity extends FragmentActivity implements OnClickListener { private RadioButton radio_btn_home; private RadioButton radio_btn_show; private RadioButton radio_btn_center; private FragmentTransaction transaction = null; private List<Fragment> fragments = new ArrayList<Fragment>(); private FragmentManager fragmentManager = null; private FragmentHome fragmentHome = new FragmentHome(); private FragmentShow fragmentShow = new FragmentShow(); private FragmentCenter fragmentCenter = new FragmentCenter(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化底部按钮对象 initTabView(); } /** * 初始化底部按钮对象 */ private void initTabView() { // 初始化数据 radio_btn_home = (RadioButton) findViewById(R.id.radio_btn_home); radio_btn_show = (RadioButton) findViewById(R.id.radio_btn_show); radio_btn_center = (RadioButton) findViewById(R.id.radio_btn_center); radio_btn_home.setOnClickListener(this); radio_btn_show.setOnClickListener(this); radio_btn_center.setOnClickListener(this); if (!radio_btn_home.isChecked()) { radio_btn_home.setChecked(true); } fragments.add(fragmentHome); fragments.add(fragmentShow); fragments.add(fragmentCenter); fragmentManager = this.getSupportFragmentManager(); transaction = fragmentManager.beginTransaction(); transaction.add(R.id.main_frg_content, fragmentHome); transaction.add(R.id.main_frg_content, fragmentShow); transaction.add(R.id.main_frg_content, fragmentCenter); transaction.show(fragmentHome).hide(fragmentShow).hide(fragmentCenter); transaction.commitAllowingStateLoss(); } @Override public void onClick(View v) { switch (v.getId()) { // 点击的首页数据 case R.id.radio_btn_home: switchFragment(0); break; case R.id.radio_btn_show: switchFragment(1); break; case R.id.radio_btn_center: switchFragment(2); break; default: // 默认选中首页 switchFragment(0); break; } } /** * 更改Fragment对象 * * @param index */ private void switchFragment(int index) { transaction = fragmentManager.beginTransaction(); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); for (int i = 0; i < fragments.size(); i++) { if (index == i) { transaction.show(fragments.get(index)); } else { transaction.hide(fragments.get(i)); } } transaction.commit(); } }
7、总结
在上面,我们只是介绍了怎么使用FragmentActivity和FragmentManager对Fragment进行管理,以及如何进行缓存处理。我们并没有介绍如何刷新,这个下拉刷新是一个很重要的功能,我们总不能因为使用了这种控件,为用户节约流量,却要用户再次加载才刷新数据吧。
这里推荐使用第三方的下拉刷新控件,github上有一个pulltorefresh这样的第三方的库,大家可以下载看看,使用一下。
如果掌握上面的缓存处理以及下拉刷新,其实新浪微博的首页也就基本出来了。哈哈
FragmentActivity与Fragment一起使用的缓存问题