我正在从parse.com下载Parse数据字段并异步调整每个中包含的图像的大小。当视图膨胀时,图像的第一页不会调整大小。视图被回收后,它们会正确显示。
我首先尝试调整done
GetDataCallback
部分中的图片大小并看到了大图片。接下来,我使用相同的结果自己实现了线程:第一个图像屏幕最初显示不正确,但是当它们离开屏幕并返回时固定。
作为测试,我接下来尝试直接获取数据(不是getDataInBackground
)并调整大小并且工作正常,但显然处理时间增加了。我认为该问题与此测试引起的线程有关。
一些代码:
@Override
public void done(List<Listing> listingList, ParseException e) {
/* scale and save the image back to parse object */
final float scale = getResources().getDisplayMetrics().density;
if (e == null) {
Log.d("listing", "Retrieved " + listingList.size() + " listings");
/* clear adapter before populating */
adapter.clear();
/* iterate through listings and create listing objects */
for (Listing listingObject : listingList) {
//listingObject.resizeImage(scale);
new ResizeImages().execute(listingObject);
listings.add(listingObject);
}
}
else {
Log.d("listing", "Error: " + e.getMessage());
}
}
});
异步调整大小:
private class ResizeImages extends AsyncTask<Listing, Void, Listing> {
protected Listing doInBackground(Listing... params) {
Listing listing = params[0];
final float scale = getResources().getDisplayMetrics().density;
try {
byte[] data = listing.getFile().getData();
/* Decode the byte array into BitMap to be displayed on device */
Bitmap bitmap = BitmapFactory
.decodeByteArray(
data, 0,
data.length);
/* scale image and put back into parse object */
if (scale <= 1.0) {
bitmap = Bitmap.createScaledBitmap(bitmap, 134, 134, false);
} else if (scale <= 1.5) {
bitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, false);
}
...
/* put image back into byte data and put back in "this" */
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] scaledData = stream.toByteArray();
bitmap.recycle();
Log.d("Resizer", "Image resized.");
ParseFile photoFile = new ParseFile("image.jpeg", scaledData);
listing.setFile(photoFile);
} catch (ParseException e) {
e.printStackTrace();
}
return listing;
}
protected void onPostExecute(Listing listing) {
Log.d("Resizer: ", "Resizing done");
}
}
修改
我的修复涉及将`onPostExecute'更改为:
protected void onPostExecute(Listing listing) {
Log.d("Resizer: ", "Resizing done");
listings.add(listing); // this line from UI thread moved here
adapter.notifyDataSetChanged(); // this line was new
}
我在下面的答案中提供了一种更通用的异步调整位图大小的方法。
答案 0 :(得分:0)
原来问题是,未通知适配器数据已更改。因此,当ListView拉出前几张图片时,它们就是原始尺寸的图片。为了使这个更通用,并希望将来帮助某人,这里是如何异步调整位图的大小:
// in your UI thread
new ResizeImages().execute(mBitmap);
// in your class
private class ResizeImages extends AsyncTask<Bitmap, Void, Listing> {
protected Listing doInBackground(Bitmap... params) {
Bitmap bitmap = params[0]; // grab the first bitmap.. could grab more and
// do multiple per thread
try {
/* scale image however you wish. here we scale to 200x200 px */
bitmap = Bitmap.createScaledBitmap(bitmap, 200, 200, false);
/* put image back into byte data if you need to */
//ByteArrayOutputStream stream = new ByteArrayOutputStream();
//bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
//byte[] scaledData = stream.toByteArray();
/* put data back into bitmap if you need to */
//Bitmap scaledBitmap = BitmapFactory
// .decodeByteArray(
// scaledData, 0,
// scaledData.length);
/* recycle unneeded bitmap */
bitmap.recycle();
Log.d("Resizer", "Image resized.");
} catch (ParseException e) {
e.printStackTrace();
}
protected void onPostExecute(Bitmap bitmap) {
Log.d("Resizer: ", "Resizing done");
resizedBitmap = bitmap; // save resized bitmap into your class
// variable
bitmaps.add(bitmap); // here bitmaps is an list of bitmaps,
// like List<Listing> listingList
/* notify adapter that the data has changed */
adapter.notifyDataSetChanged();
}
}