ListView優化adapter getview的兩種方式ViewHolder vs HolderView

dimo 8年前發布 | 11K 次閱讀 Android開發 移動開發

來自: http://www.jcodecraeer.com//a/anzhuokaifa/androidkaifa/2014/1021/1814.html


一、ViewHolder方式

如果你還沒聽說過ViewHolder,那么你該去好好看看官方文檔了,而不是埋頭寫代碼。

一個ListView的item布局中需要賦值的子元素太多為了避免重復的調用FindViewById方法,我們一般考慮使用ViewHolder方式來實現BaseAdapter。

如下:

//在外面先定義,ViewHolder靜態類
static class ViewHolder
{
    public ImageView img;
    public TextView title;
    public TextView info;
}
//然后重寫getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView == null)
    {
        holder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.list_item, null);
        holder.img = (ImageView)item.findViewById(R.id.img)
        holder.title = (TextView)item.findViewById(R.id.title);
        holder.info = (TextView)item.findViewById(R.id.info);
        convertView.setTag(holder);
    }else
    {
        holder = (ViewHolder)convertView.getTag();
    }
        holder.img.setImageResource(R.drawable.ic_launcher);
        holder.title.setText("Hello");
        holder.info.setText("World");
    }

    return convertView;
}

ViewHolderconvertView第一次inflate的時候綁定了相關的子元素,并被convertView保存下來(setTag方法),當相同的convertView再次需要顯示的時候直接調用convertView的getTag取出ViewHolder,并對ViewHolder中的元素賦值。使用ViewHolder模式避免了沒有必要的調用findViewById():因為太多的findViewById也會影響性能,這點不容易考慮到。

 

二、HolderView方式

在HolderView方式中,目的同樣是為了避免反復的調用findViewById,但是我們將這個findViewByIdde 任務交給了一個HolderView對象

@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    HolderView holderView;
    // Important to not just null check, but rather to a instanceof
    // since we might get any subclass of view here.
    if (convertView instanceof HolderView) {
        holderView = (HolderView) convertView;
    } else {
        holderView = new HolderView(mContext);
    }
    holderView.bind("標題", R.drawable.ic_launcher, "sajsa");
    return holderView;
}
public class HolderView extends GridLayout {
    private ImageView img;
    private TextView title;
    private TextView info;
    public HolderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        View v = LayoutInflater.from(context).inflate(R.layout.list_item, this);
        title = (TextView) v.findViewById(R.id.title);
        img = (ImageView)item.findViewById(R.id.img)
        info = (TextView)item.findViewById(R.id.info);
    }
    public void bind(String stringtitle,int imgrsc, String stringinfo) {
        title.setText(stringtitle);
        img.setImageResource(imgrsc);
        info.setText(stringinfo);
    }
}

HolderView自己維護一個子元素的集合,同時對外提供綁定數據的公共方法bind。HolderView方式的思想是:對于ListView來講,每一個Item本身是同一個類只是數據不同。但是需要注意的是使用HolderView方式在Adapter中getView返回的是HolderView對象。

總結:ViewHolder方式使用簡單,HolderView方式更符合面向對象規范。

 本文由用戶 dimo 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!