2015-07-02 19 views
5

Ho un RecyclerView con GridLinearLayout e un adattatore personalizzato. Il contenuto di ogni oggetto è un'immagine scaricata usando un json e analizzandola.Prevent RecyclerView mostra il contenuto precedente durante lo scorrimento

Fondamentalmente è una griglia di immagini.

Tutto funziona quasi bene, ma tuttavia, quando scorrendo verso il basso il contenuto, e il risalendo, mostra i punti di vista precedenti in ogni articolo per meno di un secondo, e poi mostrare nuovamente l'immagine corretta.

Cosa posso fare per prevenire o risolvere questo problema? Grazie in anticipo per qualsiasi aiuto e/o guida che potresti fornire.

Questo è il codice dell'adattatore:

package jahirfiquitiva.project.adapters; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.support.v7.graphics.Palette; 
import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.animation.Animation; 
import android.view.animation.AnimationUtils; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.ProgressBar; 
import android.widget.TextView; 

import jahirfiquitiva.project.activities.WallpapersActivity; 
import com.koushikdutta.async.future.FutureCallback; 
import com.koushikdutta.ion.Ion; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.WeakHashMap; 

import jahirfiquitiva.project.R; 

public class WallpapersAdapter extends RecyclerView.Adapter<WallpapersAdapter.WallsHolder> { 

    public interface ClickListener { 
     void onClick(WallsHolder view, int index, boolean longClick); 
    } 

    private ArrayList<HashMap<String, String>> data; 
    private final Context context; 
    private boolean usePalette = true; 
    private final ClickListener mCallback; 
    private final Map<String, Palette> mPaletteCache = new WeakHashMap<>(); 

    public WallpapersAdapter(Context context, ClickListener callback) { 
     this.context = context; 
     this.data = new ArrayList<>(); 
     this.mCallback = callback; 
    } 

    public void setData(ArrayList<HashMap<String, String>> data) { 
     this.data = data; 
     notifyDataSetChanged(); 
    } 

    @Override 
    public WallsHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     LayoutInflater inflater = LayoutInflater.from(context); 
     return new WallsHolder(inflater.inflate(R.layout.wallpaper_item, parent, false)); 
    } 

    @Override 
    public void onBindViewHolder(final WallsHolder holder, int position) { 
     Animation anim = AnimationUtils.loadAnimation(context, android.R.anim.fade_in); 
     HashMap<String, String> jsondata = data.get(position); 

     holder.name.setText(jsondata.get(WallpapersActivity.NAME)); 
     final String wallurl = jsondata.get(WallpapersActivity.WALL); 
     holder.wall.startAnimation(anim); 
     holder.wall.setTag(wallurl); 

     Ion.with(context) 
       .load(wallurl) 
       .asBitmap() 
       .setCallback(new FutureCallback<Bitmap>() { 
        @Override 
        public void onCompleted(Exception e, Bitmap result) { 
         holder.progressBar.setVisibility(View.GONE); 
         if (e != null) { 
          e.printStackTrace(); 
         } else if (holder.wall.getTag() != null && holder.wall.getTag().equals(wallurl)) { 
          holder.wall.setImageBitmap(result); 
          if (usePalette) { 
           Palette p; 
           if (mPaletteCache.containsKey(wallurl)) { 
            p = mPaletteCache.get(wallurl); 
           } else { 
            p = new Palette.Builder(result).generate(); 
            mPaletteCache.put(wallurl, p); 
           } 
           if (p != null) { 
            Palette.Swatch wallSwatch = p.getVibrantSwatch(); 
            if (wallSwatch != null) { 
             holder.titleBg.setBackgroundColor(wallSwatch.getRgb()); 
             holder.titleBg.setAlpha(1); 
             holder.name.setTextColor(wallSwatch.getTitleTextColor()); 
             holder.name.setAlpha(1); 
            } 
           } 
          } 
         } 
        } 
       }); 
    } 

    @Override 
    public int getItemCount() { 
     return data.size(); 
    } 

    public class WallsHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { 

     public final View view; 
     public final ImageView wall; 
     public final TextView name; 
     public final ProgressBar progressBar; 
     public final LinearLayout titleBg; 

     WallsHolder(View v) { 
      super(v); 
      view = v; 
      wall = (ImageView) v.findViewById(R.id.wall); 
      name = (TextView) v.findViewById(R.id.name); 
      progressBar = (ProgressBar) v.findViewById(R.id.progress); 
      titleBg = (LinearLayout) v.findViewById(R.id.titlebg); 

      view.setOnClickListener(this); 
      view.setOnLongClickListener(this); 
     } 

     @Override 
     public void onClick(View v) { 
      int index = getLayoutPosition(); 
      if (mCallback != null) 
       mCallback.onClick(this, index, false); 
     } 

     @Override 
     public boolean onLongClick(View v) { 
      int index = getLayoutPosition(); 
      if (mCallback != null) 
       mCallback.onClick(this, index, true); 
      return false; 
     } 
    } 
} 

risposta

3

Come suggerisce il nome RecyclerView ricicla i punti di vista per ottimizzare la memoria in modo da visualizzare il contenuto della vista precedente. Poiché stai caricando l'immagine da internet, è necessario poco tempo per caricare l'immagine in modo da poter osservare il contenuto dell'immagine precedente. Puoi fare una delle seguenti cose.

1) Impostare un'immagine predefinita da risorsa locale prima di caricare immagine reale, preferibilmente un'immagine di piccole dimensioni per preservare memory.something simili

//load default image first     
holder.wall.setImageResource(R.id.your_default_image_resource); 
//load actual image 
Ion.with(context) 
      .load(wallurl) 
    .asBitmap() 
    .setCallback(new FutureCallback<Bitmap>() { 
     @Override 
     public void onCompleted(Exception e, Bitmap result) { 
      holder.progressBar.setVisibility(View.GONE); 
      if (e != null) { 
       e.printStackTrace(); 
      } else if (holder.wall.getTag() != null && holder.wall.getTag().equals(wallurl)) { 
       holder.wall.setImageBitmap(result); 
       if (usePalette) { 
        Palette p; 
        if (mPaletteCache.containsKey(wallurl)) { 
         p = mPaletteCache.get(wallurl); 
        } else { 
         p = new Palette.Builder(result).generate(); 
         mPaletteCache.put(wallurl, p); 
        } 
        if (p != null) { 
         Palette.Swatch wallSwatch = p.getVibrantSwatch(); 
         if (wallSwatch != null) { 
          holder.titleBg.setBackgroundColor(wallSwatch.getRgb()); 
          holder.titleBg.setAlpha(1); 
          holder.name.setTextColor(wallSwatch.getTitleTextColor()); 
          holder.name.setAlpha(1); 
         } 
        } 
       } 
      } 
     } 
    }); 

2) Impostare la ImageView visibilità di andata/INVISIBLE prima di caricare la immagine e renderla VISIBILE di nuovo dopo che l'immagine è stata caricata.

//hide the imageview 
holder.wall.setVisibility(View.INVISIBLE); 
Ion.with(context) 
      .load(wallurl) 
    .asBitmap() 
    .setCallback(new FutureCallback<Bitmap>() { 
     @Override 
     public void onCompleted(Exception e, Bitmap result) { 
      holder.progressBar.setVisibility(View.GONE); 
      if (e != null) { 
       e.printStackTrace(); 
      } else if (holder.wall.getTag() != null && holder.wall.getTag().equals(wallurl)) { 
       //show the imageview and set bitmap 
       holder.wall.setVisibility(View.VISIBLE); 
       holder.wall.setImageBitmap(result); 
       if (usePalette) { 
        Palette p; 
        if (mPaletteCache.containsKey(wallurl)) { 
         p = mPaletteCache.get(wallurl); 
        } else { 
         p = new Palette.Builder(result).generate(); 
         mPaletteCache.put(wallurl, p); 
        } 
        if (p != null) { 
         Palette.Swatch wallSwatch = p.getVibrantSwatch(); 
         if (wallSwatch != null) { 
          holder.titleBg.setBackgroundColor(wallSwatch.getRgb()); 
          holder.titleBg.setAlpha(1); 
          holder.name.setTextColor(wallSwatch.getTitleTextColor()); 
          holder.name.setAlpha(1); 
         } 
        } 
       } 
      } 
     } 
    }); 
+0

La prima opzione ha funzionato. Il secondo mi ha dato lo stesso problema. Grazie per l'aiuto. –

0

penso che si dovrebbe aggiungere segnaposto in questo modo:

Ion.with(context).load("http://example.com/image.png") 
    .withBitmap() 
    .placeholder(R.drawable.placeholder_image) 
    .error(R.drawable.error_image) 
    .intoImageView(imageView); 

o l'immagine di default impostato in un primo momento.

holder.wall.setImageResource(R.drawable.placeholder_image); 
2

Sovrascrivi onViewRecycled (VH holder) per impostare l'immagine su null.

Ti piace questa:

public void onViewRecycled (VH holder) { 

    holder.wall.setImageBitmap(null); 
}