您的位置:首页 > 编程语言

View的复用:viewHolder

2017-11-30 09:32 453 查看
我们在开发的过程中用到ListView。

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

二、使用viewHolder类

我们都知道在getView方法中的操作是这样的:先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,找到每一个子View,如:一个TextView等。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,就是使用viewHolder,把每一个子View都放在Holder中,当第一次创建convertView对象时,把这些子view找出来。然后用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。当第二次重用convertView时,只需从convertView中getTag取出来就可以。
实现方式一


public View getView(int position, View convertView, ViewGroup parent) {
         ViewHolder holder = null;
         if (convertView == null) {
             convertView = mInflater.inflate(R.layout.lv_item, null);
             holder = new ViewHolder();
             holder.textView = (TextView)convertView.findViewById(R.id.tv_text);
             convertView.setTag(holder);
         } else {
             holder = (ViewHolder)convertView.getTag();
         }
         holder.textView.setText(mData.get(position));
         return convertView;
     }
}
 
 public static class ViewHolder {
     public TextView textView;
 }

实现方式二



public viewHold viewHold;
private Context mContext;

public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_mainlv, null);
viewHold = new viewHold(convertView);
convertView.setTag(viewHold);
} else {
viewHold= (ViewHolderUtil.viewHold) convertView.getTag();
}
viewHold.mTextView.setText("你要输入的内容");
return convertView;
}

private class viewHold {
TextView mTextView;

public viewHold(View v) {
mTextView = (TextView) v.findViewById(R.id.codecreate_scan);
}
}


三.通过自定义工具:viewHolderUtil

public class ViewHolderUtil {
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHoler = (SparseArray<View>) view.getTag();
if (viewHoler == null) {
viewHoler = new SparseArray<View>();
view.setTag(viewHoler);
}
View childrenView = viewHoler.get(id);
if (childrenView == null) {
childrenView = view.findViewById(id);
viewHoler.put(id, childrenView);
}
return (T) childrenView;
}

如何实现



@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(
R.layout.item_loglv, null);
}
MyListView listView = ViewHolderUtil.get(convertView, R.id.loglv_lv);
TextView tv = ViewHolderUtil.get(convertView, R.id.loglv_tv);
看上去是不是简单了很多




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐