ListView之getView详解

来源:互联网 发布:天天模拟器官网mac版 编辑:程序博客网 时间:2024/06/06 14:13

  首先讲下ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView的方法,这个方法会传入一个convertView的参数,返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存,创建View对象(Inflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)也是耗时操作,所以必将影响性能。Android提供了一个叫做Recycler(反复循环器)的构件,就是当ListView的Item从上方滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,相应的会从下方生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的Item的View,所以说如果能重用这个convertView,就会大大改善性能。 

  然后来看函数原型publicView getView(intposition, View convertView, ViewGroup parent),参数中position是指当前item在屏幕中的位置,convertView相当于缓存的作用。函数返回一个View作为ListView中一个item的布局。

下面看一个getView()例子:

   public View getView(int position, View convertView, ViewGroup parent) {    Fruit fruit = getItem(position); // 获取当前项的Fruit实例    View view;    ViewHolder viewHolder;    if (convertView == null) {        view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);        viewHolder = new ViewHolder();        viewHolder.fruitImage = (ImageView) view.findViewById (R.id.fruit_image);        viewHolder.fruitName = (TextView) view.findViewById (R.id.fruit_name);        view.setTag(viewHolder); // 将ViewHolder存储在View中    } else {        view = convertView;        viewHolder = (ViewHolder) view.getTag(); // 重新获取ViewHolder    }    viewHolder.fruitImage.setImageResource(fruit.getImageId());    viewHolder.fruitName.setText(fruit.getName());    return view;}

  假设一个ListView有50个item,一个屏幕最多显示ListView的10个item。当开始显示时,屏幕先显示前10个item,这10个item都是初次加载,所以convertView为空,这时候创建一个viewHolder(viewHolder起到储存和关联layout中的相关控件),然后再将viewHolder储存在要返回的View中。之后layout中的控件动态关联resource文件夹下的图片等。

  每次新加载一个item时都重复上述的动作。

  但当你向前滑动,浏览之前加载过的item时,convertView缓存的作用就会提高性能,此时,之前在该位置返回的View会作为getView()的convertView参数传入,所以convertView不为空,直接进行赋值操作,再取出之前储存在View中的viewHolder,无需创建新的View和viewHolder,性能大大提高。


原创粉丝点击