2012-11-07 125 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