我有带有图像视图的 GridView,这些图像视图是从画廊的图像缩略图中加载的。我从一个类中加载这些缩略图,在该类中我使用图像 id 和 imageview 调用方法,该方法会将位图设置为传递的 imageview。直到这里它工作得很好,但是当我们抛出网格视图时使线程暂停。
我的问题是它在滚动时会暂停,但是当从上到下滚动时,图像会在 gridview 中重复。我无法弄清楚确切的问题。帮帮我。谢谢!
这里如何设置暂停:
imagegrid.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
// Pause fetcher to ensure smoother scrolling when flinging
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
bitmapFromId.setPauseWork(true);
} else {
bitmapFromId.setPauseWork(false);
}
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
这是我在 grdiview 适配器中的获取视图:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.galleryitem, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ImageItem item = images.get(position);
holder.checkbox.setId(position);
holder.imageview.setId(position);
holder.checkbox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) v;
int id = cb.getId();
if (images.get(id).selection) {
cb.setChecked(false);
images.get(id).selection = false;
} else {
cb.setChecked(true);
images.get(id).selection = true;
}
}
});
holder.imageview.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
int id = v.getId();
ImageItem item = images.get(id);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
final String[] columns = { MediaStore.Images.Media.DATA };
Cursor imagecursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
columns, MediaStore.Images.Media._ID + " = " + item.id, null, MediaStore.Images.Media._ID);
if (imagecursor != null && imagecursor.getCount() > 0) {
imagecursor.moveToPosition(0);
String path = imagecursor.getString(imagecursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
File file = new File(path);
imagecursor.close();
intent.setDataAndType(Uri.fromFile(file), "image/*");
startActivityForResult(intent, VIEW_IMAGE);
}
}
});
holder.imageview.setLayoutParams(mImageViewLayoutParams);
// Check the height matches our calculated column width
if (holder.imageview.getLayoutParams().height != mItemHeight) {
holder.imageview.setLayoutParams(mImageViewLayoutParams);
}
bitmapFromId.DisplayImage(item.id, holder.imageview);
// holder.imageview.setImageBitmap(item.img);
holder.checkbox.setChecked(item.selection);
return convertView;
}
我的位图加载器类:
public class BitmapFromId {
MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
Context context;
Handler handler = new Handler();// handler to display images in UI thread
Resources mResources;
private static final int FADE_IN_TIME = 400;
private final Object mPauseLock = new Object();
private boolean mPaused = false;
public BitmapFromId(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(5);
this.context = context;
mResources = context.getResources();
}
public void DisplayImage(long id, ImageView imageView) {
Bitmap bitmap = null;
String _id = String.valueOf(id);
imageViews.put(imageView, _id);
bitmap = memoryCache.get(_id);
if (bitmap != null)
imageView.setImageBitmap(bitmap);
else {
queuePhoto(_id, imageView);
imageView.setBackgroundResource(R.drawable.empty_photo);
}
}
private void queuePhoto(String id, ImageView imageView) {
PhotoToLoad p = new PhotoToLoad(id, imageView);
executorService.submit(new PhotosLoader(p));
}
// decodes image
private Bitmap getImageFromId(String id) {
Bitmap bitmap;
long _id = Long.parseLong(id);
final String[] columns = { MediaStore.Images.Media.DATA };
final String orderBy = MediaStore.Images.Media._ID;
Cursor imagecursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
MediaStore.Images.Media._ID + " = " + _id + "", null, orderBy);
int count = imagecursor.getCount();
for (int i = 0; i < count; i++) {
imagecursor.moveToPosition(i);
bitmap = MediaStore.Images.Thumbnails.getThumbnail(context.getContentResolver(), _id,
MediaStore.Images.Thumbnails.MICRO_KIND, null);
return bitmap;
}
imagecursor.close();
return null;
}
// Task for the queue
private class PhotoToLoad {
public String id;
public ImageView imageView;
public PhotoToLoad(String _i, ImageView i) {
id = _i;
imageView = i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad) {
this.photoToLoad = photoToLoad;
}
@Override
public void run() {
try {
if (imageViewReused(photoToLoad))
return;
Bitmap bmp = getImageFromId(photoToLoad.id);
memoryCache.put(photoToLoad.id, bmp);
if (imageViewReused(photoToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
handler.post(bd);
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {
}
}
}
} catch (Throwable th) {
th.printStackTrace();
}
}
}
boolean imageViewReused(PhotoToLoad photoToLoad) {
String tag = imageViews.get(photoToLoad.imageView);
if (tag == null || !tag.equals(photoToLoad.id))
return true;
return false;
}
// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
bitmap = b;
photoToLoad = p;
}
public void run() {
if (imageViewReused(photoToLoad))
return;
if (bitmap != null) {
// Load the image fetched:
final TransitionDrawable td = new TransitionDrawable(new Drawable[] {
new ColorDrawable(android.R.color.transparent), new BitmapDrawable(mResources, bitmap) });
photoToLoad.imageView.setImageDrawable(td);
td.startTransition(FADE_IN_TIME);
} else
photoToLoad.imageView.setImageDrawable(null);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
public void setPauseWork(boolean pauseWork) {
if (pauseWork) {
synchronized (mPauseLock) {
mPaused = true;
}
} else {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
}
}