8

有一个简单的问题,在搜索后我想问为什么我们创建静态持有者类并在其中分配视图?请消除我的疑虑,这将对我有很大帮助。

4

3 回答 3

7

您的代码可能会findViewById()在滚动期间频繁调用ListView,这会降低性能。即使适配器返回一个膨胀的视图进行回收,您仍然需要查找元素并更新它们。避免重复使用的一种方法findViewById()是使用"view holder"设计模式。

一个ViewHolder对象将每个组件视图存储在 Layout 的标签字段中,因此您可以立即访问它们而无需重复查找它们。首先,您需要创建一个类来保存您的确切视图集。

您可以阅读Android 指南以获取更多详细信息。

  1. 因此,当您使用“View Holder”时,您可以轻松访问每个视图,而无需进行查找,从而节省宝贵的处理器周期。
  2. 拥有一个static inner class视图可以大大提高性能

您还可以查看为什么 Android 更喜欢静态类链接。

一个更有趣的链接ListView 的工作原理,在阅读了这篇博客之后,开发人员可以清楚地了解 LisView 的逻辑,以及为什么需要为 listView 实现内部静态类。

于 2012-07-19T11:41:28.443 回答
2

如果您了解 an 的AdapterView工作原理,答案也很简单。

AnAdapterView是一个视图,其子级由 确定Adapter。(AdapterView更具体地说,具体的实现,如ListView)包含比任何给定时间显示的信息更多的信息。为了优化内存消耗和性能,Adapter通常重用View代表单个项目的 s。因此,您的View对象数量少于相应的数据。

重用对象可以是Views 或的复杂层次结构ViewGroups。因此,如果您想View从该层次结构中查找单个对象,则需要依赖findViewById()方法,而当视图层次结构具有多个级别时,这将变得昂贵。因此,为了简单起见(也为了提高性能),我们使用了 View-Holder 模式,其中View我们感兴趣的单个对象被分配给一个静态内部类。

您可以参考 Lars Vogel 的Android ListView 和 ListActivity - 教程了解更多关于 View-Holder 模式的信息。

于 2012-07-19T11:33:45.937 回答
1

这是一个优化点。如果没有 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(...)
    
于 2012-07-19T11:29:12.090 回答