簡體   English   中英

在Android中的列表視圖中顯示和滾動大位圖時出現異常

[英]Exception while displaying and scrolling large bitmaps in list view in Android

我正面臨這個問題,但無法解決。 我的問題是這樣的:

  • 我有一個列表視圖。 我的列表行包含圖像視圖和一個文本視圖
  • 我有20張圖像,每張圖像都存儲在SD卡中,每張12 MB
  • 我必須在列表視圖的imageView中設置這些圖像

我可以通過以下代碼來完成它。 這是我在我的自定義適配器的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

現在請有人幫我糾正這個問題。 如何在不影響圖像質量的情況下解決此問題?

一個快速的創可貼可能有助於使用:

opt.inPreferredConfig = Bitmap.Config.RGB_565;

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

根據列表的長度,您可能必須加載/卸載圖像,因為它們在屏幕上可見/離開屏幕。

嘗試將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);
}

這樣的事情。 我匆忙做了。 祝你好運=)

嘗試根據圖像尺寸計算比例因子,並調用Bitmap.recycle()來釋放分配的內存

首先,因為圖像是12mb(即使它們只有1mb),你必須縮放它們並將它們縮小到你的imageview的尺寸。

你還可以查看outofmemory exception ......

public View getView (int position, View convertView, ViewGroup parent) 
{
//other stuffs like recycling, view holder etc...

    boolean OOME = true;
    int sample = 4;

    while(OOME)
    {
        try
        {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inSampleSize = sample; // tried with 8,12 too
            Bitmap bitmap = BitmapFactory.decodeFile(imageUri, opt);
            bitmap = bitmap.createScaledBitmap(bitmap,newWidth,newHeight,true);
            holder.imageView.setImageBitmap(bitmap);
            OOME = false;
        }
        catch(OutOfMemoryError e)
        {
            sample *= 2;
        }
    }
    return convertView;
}

我也假設,你在background thread中做所有解碼的東西 ,使你的listview scroll順利...

雖然有很多問題BitmapsListView ,這是最好的方法,我可以跟...還是我打開任何變更修改,enhancments ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM