何时使用ViewHolder
?我在ListView
和GridView
的大多数代码中都找到了这个。如果有人可以解释。
感谢。
答案 0 :(得分:3)
ViewHolder模式有什么用?
ViewHolder设计模式使您无需查找即可访问每个列表项视图,从而节省宝贵的处理器周期。具体来说,它避免了在ListView滚动期间频繁调用findViewById(),这将使它平滑。
没有ViewHolder设计模式
让我们看看我们之前在ArrayAdapterItem.java中的getView()方法
第一次加载时,convertView为null。我们必须通过findViewById()来扩充列表项布局并找到TextView。
第二次加载时,convertView不为null,好!我们不必再次膨胀它。但是我们将再次使用findViewById()。
以下次加载时,convertView绝对不是null。但是findViewById()经常被调用,它会起作用,但它会降低性能,特别是如果你的ListView中有很多项目和视图。
使用ViewHolder设计模式
现在让我们看看它如何与ViewHolder模式一起使用。
第一次加载时,convertView为null。我们必须扩充列表项布局,实例化ViewHolder,通过findViewById()找到TextView并将其分配给ViewHolder,并将ViewHolder设置为convertView的标记。
第二次加载时,convertView不为null,好!我们不必再次膨胀它。这是最好的事情,我们不必调用findViewById(),因为我们现在可以通过ViewHolder访问TextView。
以下时间加载,convertView绝对不是null。 findViewById()永远不会被再次调用,这使得我们的ListView滚动顺畅。
通过Android Adapter和 ViewHolder Pattern了解更详细的示例。
正式,
为什么是观看者?
因为,在视图持有人中保持视图对象
您的代码可能会在滚动期间经常调用findViewById() ListView,可以降低性能。即使是适配器 返回一个膨胀的视图进行回收,你仍然需要查找 元素并更新它们。一种绕过重复使用findViewById()的方法 是使用“视图持有者”设计模式。
ViewHolder对象将每个组件视图存储在标记内 布局的字段,因此您可以立即访问它们而不需要 需要反复查找它们。首先,您需要创建一个类 保持您的确切观点。
例如:
static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
然后填充ViewHolder并将其存储在布局中。
ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
convertView.setTag(holder);
现在您可以轻松访问每个视图而无需查找,从而节省了宝贵的处理器周期。
答案 1 :(得分:1)
什么时候? 如果您希望列表视图能够顺利滚动,那么它应该是响应式的。
<强>为什么吗 当您使用ViewHolder模式时,不是每次滚动时创建自定义行,而是重用向下滚动时隐藏的布局视图。 否则,您将一直在膨胀您的自定义lsitview布局行,它会使UI无响应,并可能会显示弹出对话框,如应用程序没有响应ok和取消选项。