适配器类中的持有人类

时间:2012-07-19 11:14:47

标签: android adapter

有一个简单的问题,在搜索后我想问为什么我们创建静态持有者类并在其中分配视图?请明确我的怀疑对我来说会有很大的帮助。

3 个答案:

答案 0 :(得分:7)

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

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

您可以阅读Android Guideline了解更多详情。

  1. 因此,当您使用“View Holder”时,您可以轻松访问每个视图,而无需查找,从而节省了宝贵的处理器周期。
  2. 视图static inner class可以大大提高效果
  3. 您还可以看到Why does Android prefer static classes链接。

    另一个有趣的链接How ListView Work ,在阅读此博客开发人员后可以清除LisView的逻辑以及为什么需要为listView实现内部静态类。

答案 1 :(得分:2)

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

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

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

有关View-Holder模式的更多信息,请参阅Lars Vogel的Android ListView and ListActivity - Tutorial

答案 2 :(得分: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(...)