我正在创建一个包含图片,视频,pdf等文件目录的应用程序。我目前正在为图片显示缩略图。我使用RecyclerView和ViewHolder来显示每个代表照片项目的列表项目。然后我使用AsyncTask一次下载一个Bitmaps,并将它们存储在一个Hashmap中。除非我快速向下滚动大量照片,否则一切正常。列表底部随机项目的占位符图像被替换为已经加载到列表顶部的缩略图。当后台线程到达底部的图像时,正确的图像会替换错误的图像。所有的缩略图加载后,一切都按预期工作。使用AsyncTask bug将位图缩略图加载到RecyclerView中
以下是AsyncTask的代码。我认为这个问题与我传递给构造函数的位置整数有关。位置变量表示适配器中的位置。也许有一种方法可以确保图像正在加载onPreExecute()中的占位符图像吗?
/**
* AsyncTask to download the thumbnails in the RecyclerView list.
*/
private class CreateThumbnail extends AsyncTask<Void, Void, android.graphics.Bitmap> {
// ******
// FIELDS
// ******
private ImageView mPreviewInstance;
private File mFile;
private RelativeLayout.LayoutParams lp;
private FileHolder mFileHolder;
private int mPosition;
private UUID mId;
private FolderFile mFolderFile;
// ***********
// Constructor
// ***********
/**
* @param holder - ViewHolder passed for the list item.
* @param position - position in the Adapter.
* @param id - id for list item stored in database.
*/
private CreateThumbnail(FileHolder holder, int position, UUID id) {
mPosition = position;
mFileHolder = holder;
mPreviewInstance = mFileHolder.mImagePreview;
mId = id;
mFolderFile = FolderFileLab.get(getContext()).getFolderFile(mId);
}
// ****************
// OVERRIDE METHODS
// ****************
@Override
protected void onPreExecute() {
}
@Override
protected Bitmap doInBackground(Void... params) {
FolderFileLab lab = FolderFileLab.get(getContext());
if (!lab.getCurrentMap().containsKey(mId)) {
mFile = lab.getPhotoFile(mFolderFile);
// Create Bitmap (Biggest use of memory and reason this background thread exists)
Bitmap bitmap = PictureUtils.getScaledBitmap(
mFile.getPath(), getActivity());
// Scales Bitmap down for thumbnail.
Bitmap scaledBitmap;
if (bitmap.getWidth() >= bitmap.getHeight()) {
scaledBitmap = Bitmap.createBitmap(bitmap, bitmap.getWidth()/2
- bitmap.getHeight()/2,
0, bitmap.getHeight(), bitmap.getHeight());
} else {
scaledBitmap = Bitmap.createBitmap(bitmap, 0, bitmap.getHeight()/2
- bitmap.getWidth()/2,
bitmap.getWidth(), bitmap.getWidth());
}
// Cache bitmap
HashMap<UUID, Bitmap> map = lab.getCurrentMap();
map.put(mId, scaledBitmap);
lab.updateMap(map);
return scaledBitmap;
} else {
// If Hashmap already contains the id get the Bitmap.
return lab.getCurrentMap().get(mId);
}
}
@Override
protected void onPostExecute(Bitmap bitmap) {
// Checks to see if the bitmap is still displayed in the list. If not nothing happens.
// If it is then it displays the image.
if (mPreviewInstance.getVisibility() == View.VISIBLE && mFileHolder.getPosition()
== mPosition && bitmap != null) {
// Formatting for thumbnail
lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout
.LayoutParams.WRAP_CONTENT);
lp.setMargins(7, 7, 7, 0);
// Displaying thumbnail on UI thread.
mPreviewInstance.setLayoutParams(lp);
mPreviewInstance.setBackground(null);
mPreviewInstance.setImageBitmap(bitmap);
}
}
}
这里是一些相关的适配器代码,其中AsyncTask启动。
@Override
public void onBindViewHolder(FileHolder holder, int position) {
FolderFile file = mFiles.get(position);
holder.bindFile(file);
if (file.isPhoto()) {
createThumbnail = new CreateThumbnail(holder, position,file.getId());
createThumbnail.execute();
}
}
它的东西与您的适配器,显示,看起来像 – tyczj
你是对的,它在适配器。 –