所以我希望我的应用能够在列表视图中有效地显示图像以防止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;
}
非常感谢任何有关如何修复它的见解!
答案 0 :(得分:0)
这里有多个问题。
1)您没有使用listview正确。如果不是null,你的getView应该重用convertView,如果它是null,则只创建一个新视图。你不是。这使得您的代码完全没有效率,根本就没有回收。
2)您的解码功能不解码位图。它只解码bitmap-inJustDecodeBounds的大小设置为true。所以你总是会返回null。
3)您没有将位图保存在任何形式的缓存中。这意味着每次调用getView时都会解码位图,每次滚动事件的每行都会解码一次。实际上,你做的事情要比不努力提高效率更糟糕。
4)你用资源做这件事。资源在启动时已经膨胀为完整的位图。正确完成后,这种优化仅适用于图像文件。
5)你在资源的可绘制中坚持使用位图。这是在启动时为您完成的。
如果您正在使用从网上下载的位图文件或位图,则这是一项必需的优化。通过你正在做的事情,你实际上正在降低性能并伤害你的应用程序。