getView()的两种实现有什么区别?

时间:2011-05-19 14:13:52

标签: android listview

任何人都可以解释两种getView()实现之间的区别吗?

第一个只检查convertView是否为空;如果它为null,则膨胀一个新的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 个答案:

答案 0 :(得分:5)

第二种模式创建ViewHolder的静态实例,并在第一次加载时将其附加到视图项,然后将在未来的调用中从该视图标记中检索

getView()被非常频繁地调用,尤其是在滚动大的元素列表时,实际上每次滚动时都会看到listview项目。

这会阻止findViewById()多次被调用无用,将视图保留在静态引用上,这是保存一些资源的好模式(特别是当你需要引用listview项目中的许多视图时)。

答案 1 :(得分:1)

使用viewHolder可以防止每次需要在屏幕上绑定视图时调用findviewById()。这意味着视图被夸大,并且连接到它的资源只被初始化一次(通胀,findById,听众,内容不会像静态标题那样改变)。所以使用它可以在使用列表时提供更好的性能,因此总是推荐的方法。