2012-11-07 69 views
1

我们目前正在使用大学的列表视图。我的讲师给了我们一个简单的应用程序,它将邮件消息显示在列表中,当用户选择一个应用程序时,它会在新的活动中显示消息的内容。我明白所发生的一切,但我想清除一些灰色地带!Android ListView布局充气器

基本上我想知道这部分的代码是做什么的?

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 

    View v = convertView; 
    if (v == null) { 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.inbox_row, null); 
    } 

此方法位于扩展ArrayAdapter的类中。我是否认为这是某种形式的回收?当视图去和屏幕上?...

任何帮助,非常感谢。谢谢。

+0

http://www.youtube.com/watch?v=wDBM6wVEO70。看看链接。你的问题可能已经回答了。 – Raghunandan

+1

如果列表中有三个项目,并且屏幕上有三个ListView中的空间,getView()将被调用三次,并使用空视图来创建这三行。您无法回收目前正在使用的行。 – Raghunandan

+0

好吧,我明白了,是基本上将视图放到列表中的视图v = vi.inflate(.layout.inbox_row,null)的布局充气器? – Javacadabra

回答

4

这正是你所说的一种回收形式。

膨胀的布局需要大量的内存和大量的时间,所以为了提高效率,系统会传递给你刚刚离开屏幕的内容,并且你可以简单地更新它的文本和图像并将它们返回给UI。因此,例如,如果您的列表视图在其列表中显示6个项目(由于它的高度),它将只膨胀6个项目,并且在滚动期间它只是继续回收它们。

有一些额外的优化技巧,你应该使用,我敢肯定,评论者发布的视频链接将解释他们。

编辑

这个例子是商店物品的ArrayAdapter,但你可以把它到任何你所需要的。 适配器执行UI和数据之间的匹配和分隔层。

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    if (convertView == null) 
    convertView = newView(); 

    // Store is the type of this ArrayAdapter 
    Store store = getItem(position); 
    Holder h = (Holder) convertView.getTag(); 

    // And here I get the data and address them to the UI 
    // as you can see, if the convertView is not null, 
    // I'm not creating a new one, I'm just changing text, images, etc 
    h.storeName.setText(store.getStoreName()); 
    h.address.setText(store.getAddressLine1()); 
    h.postcode.setText(store.getPostCode()); 
    h.distance.setText(store.getDistance()); 

    return convertView; 
} 

// I like to separate in a different method when the convertView is null 
// but that's me being organisation obsessive 
// but it also makes easy to see which methods are only being called the 1st time 
private View newView() { 
    LayoutInflater inf = LayoutInflater.from(getContext()); 
    View v = inf.inflate(R.layout.map_result_list, null); 
    Holder h = new Holder(); 
    // here we store that holder inside the view itself 
    v.setTag(h); 

    // and only call those findById on this first start 
    h.storeName = (TextView) v.findViewById(R.id.txtLine1); 
    h.address = (TextView) v.findViewById(R.id.txtLine2); 
    h.postcode = (TextView) v.findViewById(R.id.txtLine3); 
    h.distance = (TextView) v.findViewById(R.id.txtDistance); 

    return v; 
} 

// this class is here just to hold reference to the UI elements 
// findViewById is a lengthy operation so this is one of the optimisations 
private class Holder { 
    TextView storeName; 
    TextView address; 
    TextView postcode; 
    TextView distance; 
} 
+0

我明白你的意思了。但是当它被调用6次并且v不再为空时会发生什么?还是有更多的事情在幕后进行,听取屏幕上的视图并通过将其设置为空来释放v? – Javacadabra

+0

no no ...我建议你观看这个家伙评论的视频并给我一分钟我会用一个完整的ArrayAdapter实现 – Budius

+1

的示例代码更新我的答案,就像你在例子中看到的那样,v返回的是完全正确的这是你之前膨胀的同一个,然后在你的代码中,你只是将它重新命名为另一个位置上的视图。 – Budius