Android-Image GridView gallery和LruCache-图像不断变化

Android-Image GridView gallery和LruCache-图像不断变化,android,android-gridview,baseadapter,android-lru-cache,Android,Android Gridview,Baseadapter,Android Lru Cache,我根据LruCache使用示例编写了这个适配器类。我遇到的问题如下: 如果我快速滑动,GridView会向下或向上滚动很远(位图尚未缓存),那么图像将使用错误的位图绘制,而不是保持为空。图像在GridView静止(不滚动)时不断变化,直到最后加载了正确的图像,然后一切正常。我看不出我的代码有什么问题……有没有想过如何避免这种情况 public class ImageGalleryAdapter extends BaseAdapter { @SuppressLint("NewApi")

我根据LruCache使用示例编写了这个适配器类。我遇到的问题如下:

如果我快速滑动,GridView会向下或向上滚动很远(位图尚未缓存),那么图像将使用错误的位图绘制,而不是保持为空。图像在GridView静止(不滚动)时不断变化,直到最后加载了正确的图像,然后一切正常。我看不出我的代码有什么问题……有没有想过如何避免这种情况

public class ImageGalleryAdapter extends BaseAdapter {
    @SuppressLint("NewApi")

    private MyLruCache mMemoryCache;
    int size;
    BaseAdapter adapter;
    LayoutInflater mInflater;
    ArrayList<ImageItem> photos;
    Context con;
    ContentResolver cr;


    @SuppressLint("NewApi")
    public ImageGalleryAdapter(ArrayList<ImageItem> photoList,Context con, int size, GridView gridView) { 
        this.photos=photoList;
        this.size=size;
        this.con=con;
        adapter=this;

        mInflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        cr = con.getContentResolver();
        final int memClass = ((ActivityManager)con.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();

        // Use 1/8th of the available memory for this memory cache.
        final int cacheSize = 1024 * 1024 * memClass / 4;

        mMemoryCache = new MyLruCache(cacheSize) {

            @SuppressLint("NewApi")
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in bytes rather than number of items.
                return bitmap.getByteCount();   
            }

        };
    } 

    public int getCount() {   return photos.size();   } 
    public Object getItem(int position) {   return photos.get(position); } 
    public long getItemId(int position) {   return position;   } 

    @SuppressLint("InflateParams")
    public View getView( final int position, View convertView, ViewGroup parent) { 
        ImageHolder holder;
        if (convertView == null) { 
            holder = new ImageHolder();
            convertView = mInflater.inflate(R.layout.image_gallery_item, null);
            holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
            holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
            convertView.setTag(holder);
        } else { holder = (ImageHolder) convertView.getTag(); }

        FrameLayout.LayoutParams params=(FrameLayout.LayoutParams)holder.imageview.getLayoutParams();
        params.width=size; params.height=size;
        holder.imageview.setLayoutParams(params);


        final Bitmap bm = mMemoryCache.getBitmapFromCache(photos.get(position).filename);
        if (bm == null){
            mMemoryCache.getNewBitmap(holder.imageview, position);

        }

         if(bm!=null && !bm.isRecycled()){
            holder.imageview.setImageBitmap(bm);
            holder.imageview.setScaleType(ScaleType.FIT_XY);

        }
        else{
            holder.imageview.setImageResource(R.drawable.loading);
        }

        return convertView; 
    } 

    class ImageHolder {
        ImageView imageview;
        CheckBox checkbox;
    }


    class MyLruCache extends LruCache<String, Bitmap>{

        public MyLruCache(int maxSize) {
            super(maxSize);
        }

        @SuppressLint("NewApi")
        public void addBitmapToCache(String key, Bitmap bitmap) {
            if (getBitmapFromCache(key) == null) {
                put(key, bitmap);   
            }   
        }

        @SuppressLint("NewApi")
        public Bitmap getBitmapFromCache(String key) {
            return (Bitmap) get(key);   
        }


        public void getNewBitmap(ImageView imageview, int position) {
            BitmapWorkerTask task = new BitmapWorkerTask(imageview);
            task.execute(photos.get(position));
        }

        class BitmapWorkerTask extends AsyncTask<ImageItem, Void, Bitmap>{

            private final WeakReference<ImageView> imageViewReference;
            ImageItem item;
            public BitmapWorkerTask(ImageView imageView) {
                // Use a WeakReference to ensure the ImageView can be garbage collected
                imageViewReference = new WeakReference<ImageView>(imageView);
            }

            @Override
            protected Bitmap doInBackground(ImageItem... params) {
                ImageItem item = params[0];
                this.item=item;
                String filename = item.filename;
                final Bitmap bitmap = getBitmapForImageItem(item);
                mMemoryCache.addBitmapToCache(String.valueOf(filename), bitmap);
                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                if (imageViewReference != null && bitmap != null) {
                    final ImageView imageView = (ImageView)imageViewReference.get();
                    if (imageView != null) {
                        imageView.setScaleType(ScaleType.FIT_XY);
                        imageView.setImageBitmap(bitmap);
                    }
                }
            }
        } 
    }

    public Bitmap getBitmapForImageItem(ImageItem item){
        long imageID=item.imageId;
        Bitmap bm = null;
        if(!item.isVideo){
            bm=MediaStore.Images.Thumbnails.getThumbnail( cr, imageID, MediaStore.Images.Thumbnails.MICRO_KIND, null);
        }
        else{
            bm=MediaStore.Video.Thumbnails.getThumbnail( cr, imageID, MediaStore.Video.Thumbnails.MICRO_KIND, null);
        }

         if(bm==null){
            try{
                Bitmap newbitmap=F.bitmapInScreenSizeFromPath(item.filename, con, 70, 70);
                bm=F.cropAndScaleBitmap(newbitmap, 70, 70);
                newbitmap.recycle(); 
            }catch(Exception e){}
        }
        return bm; 
    }


}
公共类ImageGalleryAdapter扩展了BaseAdapter{
@SuppressLint(“新API”)
私人糜烂;
整数大小;
基本适配器;
拉平机;
ArrayList照片;
上下文con;
内容分解器cr;
@SuppressLint(“新API”)
公共ImageGalleryAdapter(ArrayList照片列表、上下文con、int大小、GridView GridView){
这个。照片=照片列表;
这个。大小=大小;
这个.con=con;
适配器=此;
mInflater=(LayoutInflater)con.getSystemService(Context.LAYOUT\u INFLATER\u SERVICE);
cr=con.getContentResolver();
final int memClass=((ActivityManager)con.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
//将可用内存的1/8用于此内存缓存。
最终int cacheSize=1024*1024*memClass/4;
mMemoryCache=新的MyLruCache(缓存大小){
@SuppressLint(“新API”)
受保护的int-sizeOf(字符串键、位图){
//缓存大小将以字节为单位,而不是以项目数为单位。
返回bitmap.getByteCount();
}
};
} 
public int getCount(){return photos.size();}
公共对象getItem(int位置){return photos.get(position);}
公共长getItemId(int位置){return position;}
@SuppressLint(“充气参数”)
公共视图getView(最终int位置、视图转换视图、视图组父级){
图像支架;
如果(convertView==null){
支架=新的图像支架();
convertView=mInflater.充气(R.layout.image\u gallery\u项目,空);
holder.imageview=(imageview)convertView.findViewById(R.id.thumbImage);
holder.checkbox=(checkbox)convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(支架);
}else{holder=(ImageHolder)convertView.getTag();}
FrameLayout.LayoutParams params=(FrameLayout.LayoutParams)holder.imageview.getLayoutParams();
参数宽度=大小;参数高度=大小;
holder.imageview.setLayoutParams(参数);
最终位图bm=mMemoryCache.getBitmapFromCache(photos.get(position).filename);
如果(bm==null){
mMemoryCache.getNewBitmap(holder.imageview,位置);
}
如果(bm!=null&&!bm.isRecycled()){
holder.imageview.setImageBitmap(bm);
holder.imageview.setScaleType(ScaleType.FIT_XY);
}
否则{
holder.imageview.setImageResource(R.drawable.loading);
}
返回视图;
} 
类图像持有者{
图像视图图像视图;
复选框;
}
类MyRuCache扩展了LruCache{
公共mylucache(int-maxSize){
超级(最大尺寸);
}
@SuppressLint(“新API”)
public void addBitmapToCache(字符串键、位图){
if(getBitmapFromCache(键)==null){
put(键、位图);
}   
}
@SuppressLint(“新API”)
公共位图getBitmapFromCache(字符串键){
返回(位图)获取(键);
}
public void getNewBitmap(ImageView ImageView,int位置){
BitmapWorkerTask任务=新建BitmapWorkerTask(图像视图);
任务。执行(照片。获取(位置));
}
类BitmapWorkerTask扩展了AsyncTask{
私有最终WeakReference imageViewReference;
图像项目;
公共位图工作任务(ImageView ImageView){
//使用WeakReference确保可以对ImageView进行垃圾收集
imageViewReference=新的WeakReference(imageView);
}
@凌驾
受保护位图doInBackground(ImageItem…参数){
ImageItem项目=参数[0];
此项=项;
字符串文件名=item.filename;
最终位图=getBitmapForImageItem(项目);
mMemoryCache.addBitmapToCache(String.valueOf(filename),位图);
返回位图;
}
@凌驾
受保护的void onPostExecute(位图){
if(imageViewReference!=null&&bitmap!=null){
final ImageView ImageView=(ImageView)imageViewReference.get();
如果(imageView!=null){
imageView.setScaleType(ScaleType.FIT_XY);
设置图像位图(位图);
}
}
}
} 
}
公共位图getBitmapForImageItem(ImageItem项目){
long-imageID=item.imageID;
位图bm=null;
如果(!item.isVideo){
bm=MediaStore.Images.Thumbnails.getThumbnail(cr,imageID,MediaStore.Images.Thumbnails.MICRO_-KIND,null);
}
否则{
bm=MediaStore.Video.Thumbnails.getThumbnail(cr,imageID,MediaStore.Video.Thumbnails.MICRO_-KIND,null);
}
如果(bm==null){
试一试{
位图newbitmap=F.bitmapInScreenSizeFromPath(item.filename,con,70,70);
bm=F.cropAndScaleBitmap(newbitmap,70,70);
newbitmap.recycle();
}捕获(例外e){}
}
返回bm;
}
}

问题出在您的
位图编辑器中