有一个简单的问题,在搜索后我想问为什么我们创建静态持有者类并在其中分配视图?请消除我的疑虑,这将对我有很大帮助。
3 回答
您的代码可能会findViewById()
在滚动期间频繁调用ListView
,这会降低性能。即使适配器返回一个膨胀的视图进行回收,您仍然需要查找元素并更新它们。避免重复使用的一种方法findViewById()
是使用"view holder"
设计模式。
一个ViewHolder
对象将每个组件视图存储在 Layout 的标签字段中,因此您可以立即访问它们而无需重复查找它们。首先,您需要创建一个类来保存您的确切视图集。
您可以阅读Android 指南以获取更多详细信息。
- 因此,当您使用“View Holder”时,您可以轻松访问每个视图,而无需进行查找,从而节省宝贵的处理器周期。
- 拥有一个
static inner class
视图可以大大提高性能
您还可以查看为什么 Android 更喜欢静态类链接。
一个更有趣的链接ListView 的工作原理,在阅读了这篇博客之后,开发人员可以清楚地了解 LisView 的逻辑,以及为什么需要为 listView 实现内部静态类。
如果您了解 an 的AdapterView
工作原理,答案也很简单。
AnAdapterView
是一个视图,其子级由 确定Adapter
。(AdapterView
更具体地说,具体的实现,如ListView
)包含比任何给定时间显示的信息更多的信息。为了优化内存消耗和性能,Adapter
通常重用View
代表单个项目的 s。因此,您的View
对象数量少于相应的数据。
重用对象可以是View
s 或的复杂层次结构ViewGroups
。因此,如果您想View
从该层次结构中查找单个对象,则需要依赖findViewById()
方法,而当视图层次结构具有多个级别时,这将变得昂贵。因此,为了简单起见(也为了提高性能),我们使用了 View-Holder 模式,其中View
我们感兴趣的单个对象被分配给一个静态内部类。
您可以参考 Lars Vogel 的Android ListView 和 ListActivity - 教程了解更多关于 View-Holder 模式的信息。
这是一个优化点。如果没有 viewHolder,您每次都需要调用 findViewById 方法。使用 viewHolder,您只需调用一次。
带有 TextView 和 ImageView 的示例:
没有 ViewHolder:
if (convertView == null) { convertView = mInflater.inflate(..., null); } //Following called each time TextView tv = (TextView)convertView.findViewById(...); ImageView iv = (ImageView)convertView.findViewById(...); tv.setText(...)
使用 ViewHolder:
if (convertView == null) { convertView = mInflater.inflate(..., null); holder = new ViewHolder(); //called once holder.tv = (TextView) vi.findViewById(..); holder.iv = (ImageView) vi.findViewById(...); vi.setTag(holder); } else { holder = (ViewHolder) vi.getTag(); } holder.tv.setText(...)