2010-05-20 50 views
13

我有一個ListView自定義ArrayAdapter。此ListView中的每一行都有一個圖標和一些文本。這些圖標在後臺下載,緩存,然後使用回調,在各自的ImageViews中替換。每次運行getView()時,都會觸發從緩存或下載獲取縮略圖的邏輯。現在從適配器內部處理多個getView調用的最佳方法

,根據羅曼蓋伊:

「上有 在getView()將 叫也沒有多少倍的量級完全沒有保證。」

我看到過這種情況,因爲一行大小爲2的getView()被調用了6次!

如何更改我的代碼以避免重複的thumbnail-fetch-requests並處理視圖回收?

謝謝。

回答

8

從api。

public abstract View getView (int position, View convertView, 
           ViewGroup parent) 

convertView - 舊的視圖重用,如果可能的話。注意:你應該在使用之前檢查這個視圖是非空的並且是合適的類型。如果無法將此視圖轉換爲顯示正確的數據,則此方法可以創建新視圖。

因此,如果已經爲此特定索引調用了getView,那麼convertView將是該第一次調用返回的View對象。

你可以做類似的事情。

if(!(convertView instanceof ImageView)){ 
    convertView = new ImageView(); 
    //get image from whereever 
} else {} // ImageView already created 
+0

我如果在每個圖像加載之前寫這個,我得到和空列表 – FilipLuch 2013-12-01 19:32:47

0

最好是用縮略圖(位圖)和文本創建一個對象。如果它在對象中不可用,請閱讀縮略圖。

0

在您的適配器中創建一個ImageView對象數組,並在緩存它們時緩存它們(無論是緩存還是網頁)。例如,在getView中,在獲取ImageView之前,檢查它是否已經存在於您的本地數組中,如果是,請使用它,如果沒有獲取,則將其存儲在本地ImageView數組中以供將來使用。

14

沒錯,這可能發生在例如當您在ListView定義有

android:layout_height="wrap_content" 

。將其更改爲fill_parent/match_parent將避免它。

+1

它不會完全驅逐冗餘呼叫問題;但它有助於更​​好地衡量ListView的高度。如果正確測量高度,ListView可以正確地確定當前可見的行數,這可以減少多餘的getView()調用次數。 – Samuh 2010-05-28 11:49:23

+0

這幫助了我,即使使用水平ListView,也改變了寬度而不是高度。 – vantesllar 2014-10-08 17:35:45

+0

這是我的答案...非常感謝您節省了時間 – user2302510 2014-10-23 08:19:41

1

我m試驗同樣的問題,我改變了listView的layout_height到match_parent解決我的問題。

1

我的理解是,您需要在這裏使用ViewHolder設計模式。只是使用返回的convertView可以導致重用以前的視圖(在這種情況下分配一些其他圖像)。

public class ImageAdapter extends ArrayAdapter<String> { 

    // Image adapter code goes here. 

    private ViewHolder { 
    public ImageView imageView; 
    public String url; 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
    View view = null; 
    ViewHolder viewHolder; 
    String url = getUrl(position); 
    if (convertView == null) { 
     // There was no view to recycle. Create a new view. 
     view = inflator.inflate(R.layout.image_layout, parent, false); 
     viewHolder = new ViewHolder(); 
     viewHolder.imageView = (ImageView) view.findViewById(R.id.image_view); 
     viewHolder.url = url; 
     view.setTag(viewHolder); 
    } else { 
     // We got a view that can be recycled. 
     view = convertView; 
     viewHolder = ((ViewHolder) view.getTag()); 
     if (viewHolder.url.equals(url)) { 
      // Nothing to do, we have the view with the correct info already. 
      return view; 
     } 
    } 

    // Do work to set your imageView which can be accessed by viewHolder.imageView 

    return view; 
    } 
} 
0

我fragment.xml之有一個ListView,這ListView控件的佈局設置爲機器人:layout_height = 「WRAP_CONTENT」,後來這個ListView控件將綁定到SimpleCursorAdapter。然後我在ViewBinder中有同樣的問題被稱爲3次。將layout_height =「wrap_content」更改爲「95p」後,問題得以解決。我確實認爲「wrap_content」高度會導致此問題。 試圖修改你的Fragment.xml,我猜3次被調用的問題將不再存在。

相關問題