2016-01-08 3 views
0

Я написал этот класс адаптера на основе примеров использования LruCache. Проблема, с которой я столкнулся, заключается в следующем:Android - изображение GridView галерея с 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; 
    } 


} 

ответ

0

Проблема заключается в вашей BitmapWorkerTask onPostExecute(), что всегда установить Bitmap к ImageView и в GridView мнения повторно используются, поэтому изменения изображения, которые вы видите, является обновлением изображения при прокручиваешься и тот же ImageView был используется для различных изображений из-за длинного прокрутки.

Мое предложение, чтобы добавить позицию в вашем ImageHolder и обновить значение на getView(), то на BitmapWorkerTask onPostExecute() вы получите текущую позицию ImageView через ImageHolder, и если это не то же самое положение, как Bitmap вам не нужно чтобы обновить его, так как изображение уже прокручивается из экрана.

+0

работал как шарм. – Anonymous

 Смежные вопросы

  • Нет связанных вопросов^_^