2012-02-27 36 views
0

我正面臨此問題,但無法解決。我的問題是這樣的:在Android的列表視圖中顯示和滾動大型位圖時出現異常

  • 我有一個列表視圖。我的列表行包含一個圖像視圖和一個文本視圖
  • 我有每12 MB大小存儲在我的SD卡
  • 我在我的列表視圖

我的ImageView的設置這些圖片20幅圖片我可以通過下面的代碼來完成它。這個我在做我的自定義適配器getView方法:

public View getView (int position, View convertView, ViewGroup parent) { 
    //other stuffs like recycling, view holder etc... 
    BitmapFactory.Options opt = new BitmapFactory.Options(); 
    opt.inSampleSize = 4; // tried with 8,12 too 
    Bitmap bitmap = BitmapFactory.decodeFile(imageUri, opt); 
    holder.imageView.setImageBitmap(bitmap); 
    return convertView; 
} 

下面這段代碼工作正常,小的圖像,但嚴重破壞了大尺寸的圖像。應用程序崩潰OutOfMemoryError。如果我嘗試將inSampleSize增加到8或12,它會起作用,但圖像質量會急劇下降,並且圖像根本看不到原始圖像。我也嘗試使用imageView.setImageURI(imageUri),但文檔建議僅使用setImageBitmap

現在請有人幫我解決這個問題。如何解決這個問題,而不會影響圖像質量?

+0

這些圖像是什麼(每個12MB)?目標圖像維度是什麼? – Asahi 2012-02-27 14:12:09

回答

1

嘗試inSampleSize設置爲2或4,和規模的寬度和高度向下使用Matrix類。但正如你在另一個答案中所說的那樣,這可能會打擊業績。

float desiredWidth = 60; // the width you want your icon/image to be 
float scale = desiredWidth/actualWidth // bitmap.getWidth() for actualWidth 
// float scale = desiredHeight/actualHeight // If you want to go by a particular height 

Matrix matrix = new Matrix(); 
matrix.setScale(scale, scale); 

holder.imageView.setImageBitmap(Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false)); 
bitmap.recycle(); // ish 

第二個選項。在實例化Adapter類之前,將Cursor對象轉換爲縮略圖圖像,並將光標傳遞給適配器的構造函數,使其成爲可變類。在ListView的每個視圖行上使用相同的遊標。

Uri tUri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI; // Where thumbnails are stored 
String[] columns = { MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATE_TAKEN, MediaStore.Images.ImageColumns.DISPLAY_NAME}; 

Cursor thumbCursor = this.managedQuery(tUri, null, null, null, null); // May want to use more paramaters to filter results 
cursor.moveToFirst(); 

.... instantiate adapter, pass in cursor .... 

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

int columnIndex = cursor.getColumnIndex(MediaStore.Images.Thumbnails.DATA); 
String filePath = cursor.getString(columnIndex); 
Bitmap bitmap = BitmapFactory.decodeFile(filePath); 
holder.imageView.setImageBitmap(bitmap); 
cur.moveToNext(); 
// BitmapDrawable d = new BitmapDrawable(listActivity.getResources(), filePath); 
// holder.imageView.setImageDrawable(d); 
} 

就是這樣的。我做得很匆忙。祝你好運=)

+0

好的。我正在努力並會回覆你。 – AndroDev 2012-02-27 14:19:29

+0

我給我的答案添加了第二個選項。 – gorn 2012-02-27 14:44:54

+0

嘗試了兩個選項但沒有成功。 :( – AndroDev 2012-02-28 12:25:49

1

快速創可貼,這可能有助於將使用:

opt.inPreferredConfig = Bitmap.Config.RGB_565; 

這將加載圖片沒有alpha通道,只有每個像素使用2個字節(而不是4個字節的默認ARGB_8888 )。

根據列表的長度,您可能必須在屏幕上顯示/離開屏幕時加載/卸載圖像。

+0

它當然提高了性能,但仍然在滾動時獲得ANR。現在我將嘗試加載/卸載邏輯。 +1爲好的想法。 :) – AndroDev 2012-02-27 14:10:21

0

嘗試基於所述圖像的尺寸的比例因子和呼叫Bitmap.recycle()以釋放內存中分配

+0

如果我回收圖像,下次如果我滾動列表,它會拋出異常:試圖使用回收的圖像。 – AndroDev 2012-02-27 13:58:06

+0

你必須重新創建它,因爲它被回收 – Asahi 2012-02-27 13:59:39

+0

它會減慢列表滾動。我的列表視圖啓用了快速滾動功能。 – AndroDev 2012-02-27 14:01:35

0

首先,由於圖像是12MB(即使他們只有1MB的),你必須規模他們縮減他們imageview的尺寸。您也可以檢查outofmemory exception ...

​​

我也藉此假設,你正在做的所有的解碼東西background thread,使您的​​3210順利......

同時與BitmapsListView很多問題,這是最好的辦法我可以跟...還是我打開任何改變修改enhancments ...

+0

如果我處理OutOfMemoryError,滾動,崩潰不會發生,但從列表視圖中的圖像消失:( 此外,OutOfMemoryError發生在解碼文件本身時,而不是在imageview中設置位圖 – AndroDev 2012-02-28 07:08:31

+0

我告訴你,你必須使用異步的東西來解碼位圖,然後將其設置....這樣它將可見...你有沒有想過使用droid-fu庫.... ???它管理/幫助了很多。 ... – Farhan 2012-02-28 09:39:09

相關問題