在Android中的ListView中我们被建议采用ViewHolder来呈现视图,我们可以从很多优秀的文章中看到,那么我们来简单举个例子。
// Named as row.xml. This is just a skeleton.
<RelativeLayout>
<ImageView android:id="@+id/icon"/>
<TextView android:id="@+id/title"
android:layout_toLeftOf="@id/icon"/>
<TextView android:id="@+id/subtitle"
android:layout_toLeftOf="@id/icon"
android:layout_below="@id/title"/>
</RelativeLayout>
然后使用ViewHolder模式在getView中的代码如下:
class ViewHolder {
ImageView icon;
TextView title;
TextView subtitle;
}
// Inside the adapter
public void getView(int position, View convertView, ViewGroup parent) {
// if convertView is null, the view is newly inflated.
// else, re-assign new values.
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.row, null);
// Set up the ViewHolder.
holder = new ViewHolder();
holder.icon = (ImageView) findViewById(R.id.icon);
holder.title = (TextView) findViewById(R.id.title);
holder.subtitle = (TextView) findViewById(R.id.subtitle);
// Store the holder with the view.
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Assign values
holder.icon.setImageDrawable(some_image);
holder.title.setText(some_text);
holder.subtitle.setText(some_text);
}
采用这种模式的原因是:
1.使得ListView中的item得到复用
2.减少findViewById()方法的调用次数
但是,你不觉得这ViewHolder模式代码莫名多的跟”屎”一样长看起来会爽么?那为什么我们不自己新建一个CustomView来组合起来呢。
// Custom class for ListRow
public class ListRow extends RelativeLayout {
private ImageView mIcon;
private TextView mTitle;
private TextView mSubtitle;
public ListRow(Context context, AttributeSet attrs) {
// RelativeLayout intializations happen here.
LayoutInflater.from(context).inflate(R.layout.row, this);
// Store the views.
mIcon = (ImageView) findViewById(R.id.icon);
mTitle = (TextView) findViewById(R.id.title);
mSubtitle = (TextView) findViewById(R.id.subtitle);
}
public void setIcon(Drawable drawable) {
mIcon.setImageDrawable(drawable);
}
public void setTitle(String text) {
mTitle.setText(text);
}
public void setSubtitle(String subtitle) {
mSubtitle.setText(text);
}
}
// Inside the adapter
public void getView(int position, View convertView, ViewGroup parent) {
// if convertView is null, the view is newly inflated.
// else, re-assign new values.
ListRow row;
if (convertView == null) {
// Inflation happens automagically.
row = new ListRow(context, null);
convertView = row;
} else {
row = (ListRow) convertView;
}
// Assign values
row.setIcon(some_image);
row.setTitle(some_text);
row.setSubtitle(some_text);
}
是不是看起来简洁多了,每一个Item都被抽离出来了,标题可以包含在一个LinearLayout中,图片可以用CustomImageView描边,而且adaper中仅仅只需要调用setIcon()和setTitle()就好了。
声明:本文是一篇译文,本文来自以下的文章!!
https://sriramramani.wordpress.com/2012/07/25/infamous-viewholder-pattern/