2011-05-19 103 views
4

任何人都可以请解释两种getView()实现之间有什么区别吗?这两种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; 
} 

回答

5

第二图案创建ViewHolder的静态实例,并将其附加到该视图项目它装在第一时间,然后将它从上将来该视图标签中检索呼叫

getView ()被非常频繁地调用,特别是当你滚动列表中的大元素时,实际上每当列表视图项在滚动中变得可见时就会调用它。

这可以防止调用findViewById()很多次无用,保留一个静态引用的视图,这是一个很好的模式来保存一些资源(尤其是当你需要引用你的列表视图项目中的许多视图)。

+1

这不仅仅是findViewById(),尽管它是最常见的用例。 ViewHolder可以也应该用来存储临时数据结构,以避免getView()中的内存分配。一个很好的例子可以在这里找到:http://goo.gl/NzgTt和http://goo.gl/d4vvo ViewHolder包含一个字符缓冲区,以避免从光标获取数据时的分配。 – 2011-05-19 16:30:40

+1

相关提示=) – BFil 2011-05-19 17:19:13

1

使用viewHolder可防止每次需要在屏幕上绑定视图时调用findviewById()。这意味着视图膨胀了,连接到它的资源只被初始化一次(通胀,findById,监听器,不会像静态标题或其他内容那样改变的内容)。所以使用这种方法在使用列表的时候可以获得更好的性能,因此也就是始终推荐的方法