Android viewpager结合fragment的相关优化

本文探讨了在Android开发中,使用ViewPager结合Fragment时遇到的问题,包括Fragment的onCreateView频繁执行导致的性能问题和数据加载优化。提出了两种优化策略:缓存Fragment的rootView以避免重复inflate,以及利用setUserVisibleHint实现懒加载数据。这些优化方法旨在提高应用性能,减少资源消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前写过两个项目,都是类似于微信这样的底部四个导航,实现这样的效果方式其实比较多,当时我的做法为viewpager结合fragment

那么我在开发的工程中遇到了哪些问题,并且做了哪些优化呢?

1.由于原生的viewpager自带左右各缓存一个page的特点,每次切换fragment后再切换回来,fragment的onCreateView方法都会被重新执行,在该方法中会进行inflate等相关操作,比较消耗资源,并且inflate后的findViewByID方法也是比较耗时间的。。。个人觉得此处可以有所优化

2.往往初始化完view之后,都会去获取一次数据,这个数据可能是网络的,可能是数据库的,对于数据加载是否可以有所优化,因为内存中存在有数据,但是如果用户当前页的数据比较大,或者当前页的功能比较多,极少有可能切换到下一页的时候,viewpager的缓存效果岂不是不大了?

针对这样的情况,我做的优化工作有哪些?

1.通过既然每次onCreateView都会执行,每次都会inflate相关的布局,那么为什么不把相关的布局view拿出来,当我第一次inflate完以后,之后每次需要使用的时候直接返回就好了嘛,即在baseFragment(这是我Fragment的基类)中定义一个view类型的全局变量rootView,每次执行onCreateView的时候都先判断下rootView是否是空,如果是空的话,那么就去inflate布局,如果不是空的话,直接就将这个rootView对象返回即可。这样就有效避免了每次执行onCreateView方法都会去inflate的情况,类似于这样的判空,在app很多地方都会有。


2.对于数据加载,一般的做法就是我要用的时候才去加载数据,这就是通常说的懒加载,说到“懒”这个字的时候,就想起了单例模式中的两种方式,懒汉式和饿汉式,刚开始的时候,我真的分不清什么是懒汉式,什么是饿汉式,所谓懒汉,即对象很懒,只有当需要使用这个对象的时候,这个对象才会被创建出来,那么相对应的饿汉,就是对象很饥饿,一开始的时候就创建出来以满足需求,以后每次需要使用的时候,直接把这个对象拿过来用即可。回归刚刚的懒加载方式,fragment有一个方法叫做setUserVisibleHint,这个方法有两个特点,每当fragment当前可见或不可见时都会被回调,另外就是这个方法的调用时机早于onCreateView方法,基于这两点认识,我重写了该方法,在方法内判断对调回来的参数isVisibleToUser,如果isVisibleToUser为true,说明可见,那么马上就去加载相关的数据,否则就什么都不做,等待用户切换界面时再去加载数据,这样可以节约一点资源,Android手机的配置虽然高,但是分给每一个app的内存都是有限的,还是能节约就节约,能优化就优化。尤其是如果想做一个好的程序员,发现有的时候用eclipse写代码,会在代码的视图窗口的右侧边栏提示黄色的警报,有可能是因为多余的导包所致,这时也会想很多方法去消除这样的警报,当看到整个类都很干净后才会安心,我想对于很多同行都有类似的强迫症。。。

3.基于第二点的懒加载的认识,以及对于setUserVisibleHint方法的认识,那么之前所做的第一点优化还可以再进一步,既然数据都是在用户可见以后才去加载的,那么为什么初始化view放到用户可见之后再去做呢,要懒,就懒的彻底点,记得之前听一位老程序员说,不会“偷懒”的程序员不是好程序员,所以再一次优化时,直接在onCreateView方法中返回一个空的布局文件即可,每次用户可见时,将真正的布局inflate出来以后添加到这个容器中即可,最后我的setUserVisibleHint方法是这样的:

	@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			if (null == contentView) {
				dialog = ProgressDialog.show(getActivity(), null, null);
				contentView = mInflater.inflate(getContentID(), null);
				initViews(contentView);
				if (null != rootView) {
					((ViewGroup) rootView).addView(contentView);
				}
			}
			loadDatas();
		}
	}
将整个fragment封装成基类的话是这样的:


public abstract class BaseFragment extends Fragment {
	public static int DelayTime = 500;
	private View rootView, contentView;
	private LayoutInflater mInflater = LayoutInflater.from(App.getInstance());
	protected Handler mHandler = new Handler(Looper.getMainLooper());
	protected ProgressDialog dialog;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		if (null == rootView) {
			rootView = inflater.inflate(R.layout.layout_base_fragment,
					container, false);
			if (null != contentView) {
				((ViewGroup) rootView).addView(contentView);
			}
		}
		return rootView;
	}

	@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			if (null == contentView) {
				dialog = ProgressDialog.show(getActivity(), null, null);
				contentView = mInflater.inflate(getContentID(), null);
				initViews(contentView);
				if (null != rootView) {
					((ViewGroup) rootView).addView(contentView);
				}
			}
			loadDatas();
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		((ViewGroup) rootView).removeView(rootView);
	}

	public abstract int getContentID();

	public abstract void initViews(View contentView);

	public abstract void loadDatas();
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值