我正在創建一個包含圖片,視頻,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
你是對的,它在適配器。 –