2010-09-06 25 views
4

我有下面的屏幕,其中包含一些圖像(每個可見頁面6)。上下滾動對我來說似乎相當滯後。這就像它再次渲染圖像。滾動備份似乎比滾動下來更糟糕。通過ListView滾動瀏覽一些圖像非常滯後

任何人都知道如何提高這方面的表現來創造一個不錯的平滑滾動?

更新:圖像和文字都從我的SQLite數據庫檢索。該列表使用SimpleCursorAdapter創建。

Gallery

private class HistoryViewBinder implements SimpleCursorAdapter.ViewBinder 
{ 
    //private int wallpaperNumberIndex; 
    private int timeIndex; 
    private int categoryIndex; 
    private int imageIndex; 

    private java.text.DateFormat dateFormat; 
    private java.text.DateFormat timeFormat; 
    private Date d = new Date(); 

    public HistoryViewBinder(Context context, Cursor cursor) 
    { 
     dateFormat = android.text.format.DateFormat.getDateFormat(context); 
     timeFormat = android.text.format.DateFormat.getTimeFormat(context); 

     //wallpaperNumberIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_WALLPAPER_NUMBER); 
     timeIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_TIME); 
     categoryIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_CATEGORY); 
     imageIndex = cursor.getColumnIndexOrThrow(HistoryDatabase.KEY_IMAGE); 
    } 

    @Override 
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) 
    { 
     Log.d(TAG, "setViewValue"); 

     if (view instanceof TextView) 
     { 
      Log.d(TAG, "TextView"); 
      TextView tv = (TextView) view; 

      if (columnIndex == timeIndex) 
      { 
       Log.d(TAG, "timeIndex"); 
       d.setTime(cursor.getLong(columnIndex)); 
       tv.setText(timeFormat.format(d) + " " + dateFormat.format(d)); 
       return true; 
      } 
      else if (columnIndex == categoryIndex) 
      { 
       Log.d(TAG, "categoryIndex"); 
       tv.setText(cursor.getString(columnIndex)); 
       return true; 
      } 
     } 
     else if (view instanceof ImageView) 
     { 
      Log.d(TAG, "ImageView"); 
      ImageView iv = (ImageView) view; 

      if (columnIndex == imageIndex) 
      { 
       Log.d(TAG, "imageIndex"); 
       byte[] image = cursor.getBlob(columnIndex); 
       Bitmap bitmapImage = BitmapFactory.decodeByteArray(image, 0, image.length); 
       iv.setImageBitmap(bitmapImage); 
       return true; 
      } 
     } 

     return false; 
    } 
} 
+0

如果您可以發佈您的getView方法的代碼創建單個列表項目,我會幫助很多。 – Janusz 2010-09-06 12:52:24

+0

@Janusz我不使用getView。我使用SimpleCursorAdapter來創建這個視圖。 – mlevit 2010-09-06 13:22:35

+0

然後你可以發佈SimpleCursorAdapter的創建,並且如果你正在擴展遊標適配器bindView方法嗎? – Janusz 2010-09-06 16:08:53

回答

6

問題是每個圖像都在視圖準備顯示的時候被解碼。 ListView將回收您的視圖,這意味着當前視圖離開屏幕時將被重用,因此圖像將被覆蓋並垃圾收集。如果項目重新進入屏幕,圖像必須再次從數據庫解碼。

解碼速度合理快速,但如果用戶非常快速地更改列表中的位置,所有解碼調用將使您的列表非常滯後。

我會暗示像一個ImageCache。一個包含WeakReferences的地圖的類。每次你想要顯示一幅圖像時,你都會看看圖像是否已經在地圖上,如果WeakReference仍然指向一個對象,如果情況不是這樣,你需要對圖像進行解碼,然後將其存儲在地圖中。

看看懶惰的加載問題,這些將向您展示如何將解碼放入後臺任務,然後在加載圖像時更新列表。這是多一點努力,但它可以使列表更加快速。如果您要使用延遲加載問題的代碼示例,請嘗試使用AsyncTasks而不是線程來執行解碼。

+0

你是對的。每次我都會回滾到視圖中,它會從數據庫中檢索圖像,解碼並顯示它。你有沒有任何使用AsyncTasks進行解碼而不是線程的例子? – mlevit 2010-09-07 09:35:02

0

如果你的圖片是不是正確的大小,他們正在比例上的蒼蠅,這是不是一個便宜的操作,尤其是對於大型的圖像。確保你正在從數據庫中加載縮略圖,而不是牆紙。

此外,您可以使用Traceview找出您的時間花在哪裏。

+0

我正在使用縮略圖,但不是您在那裏看到的確切尺寸......所以它們會縮小尺寸。你認爲存儲第二個更小的僅用於列表的縮略圖會更好嗎?一旦你點擊列表項目(所以我需要更大的縮略圖),我使用原始縮略圖在它內部顯示AlertDialog。 – mlevit 2010-09-06 13:50:24

+1

@mlevit:值得一試,或者使用Traceview來查看你的時間似乎是用來調整代碼大小。也可以想象,從SQLite加載Blob非常慢 - 我從來沒有在表中存儲圖像,所以不知道性能特點。 – CommonsWare 2010-09-06 14:05:25