两种getView()实现方式有什么区别?(涉及IT技术)

4

请问两种getView()实现方式有什么区别?

第一种方式只是检查convertView是否为空,如果为空则填充一个新的View对象。然后使用适当的值设置子视图。

@Override
public View getView(int position, View convertView, ViewGroup parent) 
{           
    if(convertView == null)
    {
        LayoutInflater inflater = context.getLayoutInflater();
        convertView = inflater.inflate(R.layout.itemlayout, null, true);
    }   

    ImageView image = (ImageView) convertView.findViewById(R.id.icon);
    TextView text = (TextView) convertView.findViewById(R.id.name);     

    MyItem item = items[position];
    text.setText(item.name);
    if("male".equals(item.gender))
    {
        image.setImageResource(R.drawable.male);
    }
    else if("female".equals(item.gender))
    {
        image.setImageResource(R.drawable.female);
    }

    return convertView;
}

第二种方法被称为“ViewHolder”模式。许多开发人员表示,此方法可以节省大量内存和CPU时间。但是第一种实现方法也检查了convertView的存在。第一种方法难道没有节省一些内存吗?有没有人能更深入、更清楚地解释这两种实现方法之间的区别?非常感谢。
@Override
public View getView(int position, View convertView, ViewGroup parent) 
{       
    ViewHolder holder;

    View itemView = convertView;
    if(itemView == null)
    {
        LayoutInflater inflater = context.getLayoutInflater();
        itemView = inflater.inflate(R.layout.itemlayout, null, true);
        holder = new ViewHolder();
        holder.image = (ImageView) itemView.findViewById(R.id.icon);
        holder.text = (TextView) itemView.findViewById(R.id.name);
        itemView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) itemView.getTag();
    }

    MyItem item = items[position];
    holder.text.setText(item.name);
    if("male".equals(item.gender))
    {
        holder.image.setImageResource(R.drawable.male);
    }
    else if("female".equals(item.gender))
    {
        holder.image.setImageResource(R.drawable.female);
    }

    return itemView;
}
2个回答

5
第二种模式创建一个ViewHolder的静态实例并将其附加到视图项上,第一次加载时,然后它将从该视图标记中检索,并在以后的调用中使用。
getView() 会频繁地被调用,特别是当您滚动大量元素的列表时,事实上,每当ListView项目在滚动时变得可见时,都会调用它。
这可以防止findViewById() 被无用地多次调用,通过保持视图的静态引用,这是一种节省资源的好方法(尤其是当您需要引用许多视图在您的ListView项目中)。

1
这不仅仅是关于findViewById(),尽管它是最常见的用例。ViewHolder也可以(而且应该)用于存储临时数据结构,以避免在getView()中进行内存分配。可以在此处找到一个很好的示例:http://goo.gl/NzgTt和http://goo.gl/d4vvo ViewHolder包含一个char缓冲区,以避免从Cursor获取数据时进行分配。 - Romain Guy

1

使用viewHolder可以避免每次需要在屏幕上绑定视图时调用findviewById()。这意味着视图只被膨胀一次,并且与之连接的资源只被初始化一次(包括膨胀、findById、监听器、不会更改的内容,如静态标题等)。因此,在处理列表时使用此方法可以提高性能,因此这是始终推荐的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接