尝试有效加载位图会导致无法显示图像

时间:2016-02-26 22:08:16

标签: java android listview bitmap

所以我希望我的应用能够在列表视图中有效地显示图像以防止OOM错误。我尝试通过将图像转换为位图然后将其设置为framelayout中的背景来实现此功能,然后将此xml文件用作listview的布局。但是,它不会显示任何内容。

这是适配器类。

Size NewSize = PictureBox1.Size;
NewSize.Height = NewSize.Height * 16;
NewSize.Width = NewSize.Width * 16;
clickedPictureBox.Size = NewSize;
clickedPictureBox.SizeMode = PictureBoxSizeMode.StretchImage;

}

这是与之关联的xml文件

public class CustomAdapter extends BaseAdapter {

String [] result;
Context context;
int [] imageId;
String [] peopleId;
private static LayoutInflater inflater=null;
public CustomAdapter(MyMainActivity mainActivity, String[] prgmNameList, int[] prgmImages, String[] peopleImages) {
    // TODO Auto-generated constructor stub
    result=prgmNameList;
    context= mainActivity;
    imageId=prgmImages;
    peopleId=peopleImages;
    inflater = ( LayoutInflater )context.
            getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
    // TODO Auto-generated method stub
    return result.length;
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

public class Holder
{
    FrameLayout frame;
    ImageView pic;
    TextView tv;
    TextView imgPeople;
  }
@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    // TODO Auto-generated method stub
    Holder holder=new Holder();
    View rowView;
    rowView = inflater.inflate(R.layout.program_list_upcoming, null);
    rowView.setRotation(5);
    holder.frame=(FrameLayout) rowView.findViewById(R.id.frame);
    holder.pic = (ImageView) rowView.findViewById(R.id.frameBackPic);
    holder.imgPeople=(TextView) rowView.findViewById(R.id.peopleImage);
    holder.tv=(TextView) rowView.findViewById(R.id.textView1);
    holder.imgPeople.setText(peopleId[position]);
    holder.frame =(FrameLayout) rowView.findViewById(R.id.frame);
    holder.tv.setText(result[position]);

    Bitmap bitmap = decodeSampledBitmapFromResource(Resources.getSystem(), imageId[position],400, 130);
    BitmapDrawable myDrawable = new BitmapDrawable(this.context.getResources(), bitmap);
    holder.pic.setImageBitmap(bitmap);
    holder.pic.requestLayout();

    rowView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Toast.makeText(context, "You Clicked " + result[position], Toast.LENGTH_LONG).show();
        }
    });
    return rowView;
}

//This is to convert the imageIDs into a array of small bitmaps
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                     int reqWidth, int reqHeight) {
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

//this adjusts the size of the bitmap as its needed accordign to the layout dimentsions
public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        final int halfHeight = (int)(height / 1.5);
        final int halfWidth = (int)(width / 1.5);
        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

非常感谢任何有关如何修复它的见解!

1 个答案:

答案 0 :(得分:0)

这里有多个问题。

1)您没有使用listview正确。如果不是null,你的getView应该重用convertView,如果它是null,则只创建一个新视图。你不是。这使得您的代码完全没有效率,根本就没有回收。

2)您的解码功能不解码位图。它只解码bitmap-inJustDecodeBounds的大小设置为true。所以你总是会返回null。

3)您没有将位图保存在任何形式的缓存中。这意味着每次调用getView时都会解码位图,每次滚动事件的每行都会解码一次。实际上,你做的事情要比不努力提高效率更糟糕。

4)你用资源做这件事。资源在启动时已经膨胀为完整的位图。正确完成后,这种优化仅适用于图像文件。

5)你在资源的可绘制中坚持使用位图。这是在启动时为您完成的。

如果您正在使用从网上下载的位图文件或位图,则这是一项必需的优化。通过你正在做的事情,你实际上正在降低性能并伤害你的应用程序。