title: AsyncTask loading image RecyclerView
body: <p>I'm trying to create an app similar to that one:
  <a href="https://lh5.ggpht.com/At-pHbZqdzlgmAqY0jbiztDYIAts1wOYWGTOHibmFHuq8CFAsO49a_1w8-hGMjqUdAE3=h900">An app with some images and description (cardview) in a recyclerview</a></p>
  
  <p>First at all i load all the information for my CardView from a database
  Title of the image, Description and the URL from the image.
  When i put all that information in the RecyclerView, (title and description) shows correctly, but for the image I create a AsyncTask class to load the images from the URL and let the user don't wait to much time waiting for the app to response.</p>
  
  <p>If the user scroll slowly the images are loaded correctly and all is fine, but if i scroll to fast i have some problems, for example the image that is shown in the item 3 for example is shown to in the last item until the last item's image is loaded and refresh....</p>
  
  <p>Here some code for my adapter where i load the image:</p>
  
  <pre><code>@Override
  public void onBindViewHolder(ViewHolder holder, final int position) {
      if (holder instanceof EventosViewHolder) {
          ......
          //Load the image (getFoto() get drawable)
          if (eventoInfoAux.getFoto()==null){
              CargarImagen cargarImagen = new CargarImagen(((EventosViewHolder) holder).vRelativeLayout,eventoInfo,position);
              cargarImagen.execute();
          }else{
              ((EventosViewHolder) holder).vRelativeLayout.setBackground(eventoInfoAux.getFoto());
          }   
      }
  }
  </code></pre>
  
  <p>Here the code for the class CargarImagen:</p>
  
  <pre><code>//Clase para cargar imagenes con una tarea asíncrona desde un url de la imagen
  public class CargarImagen extends AsyncTask&lt;String, String, Boolean&gt;{
  
  //RelativeLayout donde se introduce la imagen de fondo
  RelativeLayout relativeLayout=null;
  //EventoInfo para obtener la url de la imagen
  List&lt;EventoInfo&gt; eventoInfo=null;
  //Posición de la imagen clicada
  int i;
  
  //Se cargan todos los valores de las variables necesarias desde los datos introducidos
  public CargarImagen(RelativeLayout relativeLayout,List&lt;EventoInfo&gt; eventoInfo,int i) {
      this.relativeLayout = relativeLayout;
      this.eventoInfo = eventoInfo;
      this.i = i;
  }
  
  //Pintamos el fondo de gris mientras se está cargando la imagen
  @Override 
  protected void onPreExecute() { 
      super.onPreExecute(); 
      relativeLayout.setBackgroundResource(R.color.fondo_card_view);
  }
  
  //Se realiza la carga de la imagen en segundo plano
  @SuppressWarnings("deprecation")
  @Override
  protected Boolean doInBackground(String... params) {
      //Necesario para hacer la llamada a la red
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();      
      StrictMode.setThreadPolicy(policy);
  
      //obtenemos la imagen con el metodo getBitmapFromURL
      Bitmap myImage = getBitmapFromURL(eventoInfo.get(i).url);
  
      //Si se tiene imagen se pinta, si no no se hace nada
      if (myImage !=null){
          Drawable dr = new BitmapDrawable(myImage);
          eventoInfo.get(i).setFoto(dr);
          return true;
      }
      return false;
  }
  
  //Al finalizar la carga de la imagen se pinta el fondo del relative layout
  protected void onPostExecute(Boolean result) {
      if(result){
          relativeLayout.setBackground(eventoInfo.get(i).foto);
      }   
  }
  
  //Metodo para obtener un bitmap desde una url
  public Bitmap getBitmapFromURL(String imageUrl) {
      try {
  
          URL url = new URL(imageUrl);
          HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          connection.setDoInput(true);
          connection.connect();
          InputStream input = connection.getInputStream();
          Bitmap myBitmap = BitmapFactory.decodeStream(input);
          return myBitmap;
  
      } catch (IOException e) {
          e.printStackTrace();
          return null;
      }
  }
  
  }
  </code></pre>
  
  <p>I could give you the .apk file and you could see the problem.</p>
  
  <p>Thank you in advance. :)</p>
  
  <p>Here the full code of my adapter</p>
  
  <pre><code> import java.util.List;
  
  import com.abdevelopers.navarraongoing.R;
  import com.abdevelopers.navarraongoing.detalle.DetalleActivity;
  
  import android.content.Intent;
  import android.support.v7.widget.CardView;
  import android.support.v7.widget.RecyclerView;
  import android.support.v7.widget.RecyclerView.ViewHolder;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.ViewGroup.LayoutParams;
  import android.widget.Button;
  import android.widget.RelativeLayout;
  import android.widget.TextView;
  
  public class EventosAdapter extends RecyclerView.Adapter&lt;ViewHolder&gt;{
  
      private static final int TYPE_EVENTO = 0;
      private static final int TYPE_FOOTER = 1;
  
  //lista de eventos
  private List&lt;EventoInfo&gt; eventoInfo;
  
  
  private String usuario;
  private EventoInfo  eventoInfoAux;
  private PaginaInicioActivity paginaInicio;
  
  //Se pasan los valores necesarios para obtener información de los eventos
  public EventosAdapter(List&lt;EventoInfo&gt; eventoInfo, String usuario, PaginaInicioActivity paginaInicio ) {
      this.eventoInfo = eventoInfo;
      this.usuario = usuario;
      this.paginaInicio = paginaInicio;
  }
  
  
  //Metodo para obtener el numero de items en la lista que introducimos
  @Override
  public int getItemCount() {
      return eventoInfo.size();
  }
  
  @Override
  public int getItemViewType(int position) {
      if (position + 1  == getItemCount()) {
          return TYPE_FOOTER;
      } else {
          return TYPE_EVENTO;
      }
  }
  
  //Se asignan los datos a cada uno de los elementos de la cardview
  @Override
  public void onBindViewHolder(ViewHolder holder, final int position) {
      if (holder instanceof EventosViewHolder) {
          //Obtenemos cada uno de los eventos
          eventoInfoAux = eventoInfo.get(position);
          //eventosViewHolder = holder;
  
          //Introducimos el título del evento
          ((EventosViewHolder) holder).vTitle.setText(eventoInfoAux.titulo);
          //Introdicumos la fecha y el lugar del evento
          ((EventosViewHolder) holder).vFechaLugar.setText(eventoInfoAux.fecha+", "+eventoInfoAux.lugar);
          //obtenemos el numero de asistentes al evento
          String asistentes = Integer.toString(eventoInfoAux.asistentes);
          ((EventosViewHolder) holder).vLikeButton.setText(asistentes);
  
          //Se pinta el boton de like dependiendo de si está o no like 
          if(eventoInfoAux.like){
              ((EventosViewHolder) holder).vLikeButton.setBackgroundResource(R.drawable.button_like_liked);
          }else{
              ((EventosViewHolder) holder).vLikeButton.setBackgroundResource(R.drawable.button_like);
          }
  
          //Se pinta la imagen del evento dependiendo de si está en la base de datos o no
          if (eventoInfoAux.foto==null){
              CargarImagen cargarImagen = new CargarImagen(((EventosViewHolder) holder).vRelativeLayout,eventoInfo,position);
              cargarImagen.execute();
          }else{
              ((EventosViewHolder) holder).vRelativeLayout.setBackground(eventoInfoAux.foto);
          }   
      }
  }
  
  
  
  @Override
  public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      if (viewType == TYPE_EVENTO) {
          View view = LayoutInflater.
                  from(parent.getContext()).
                  inflate(R.layout.evento_card_view, parent, false);
          return new EventosViewHolder(view,eventoInfo,usuario,paginaInicio);
      } else if (viewType == TYPE_FOOTER) {
          View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.pie_carga_pagina_inicio, parent, false);
          view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
          return new FooterViewHolder(view);
      }
      return null;
  }
  
  //Clase para crear el footerview donde se cargan más eventos
  class FooterViewHolder extends ViewHolder {
  
      public FooterViewHolder(View view) {
          super(view);
      }
  
  }
  
  //Clase para crear los eventos con su cardview
  class EventosViewHolder extends ViewHolder implements View.OnClickListener{
  
      private TextView vTitle;
      private TextView vFechaLugar;
      private Button vLikeButton;
      private RelativeLayout vRelativeLayout;
      private List&lt;EventoInfo&gt; eventoInfo;
      private String usuario;
      private LikesDDBB likesManager;
      private PaginaInicioActivity paginaInicio;
      private CardView vCardView;
  
      public EventosViewHolder(View itemView,List&lt;EventoInfo&gt; eventoInfo,String usuario, 
              PaginaInicioActivity paginaInicio) {
          super(itemView);
  
          this.paginaInicio = paginaInicio;
          this.usuario = usuario;
          vTitle = (TextView)itemView.findViewById(R.id.titulo);
          vFechaLugar =  (TextView) itemView.findViewById(R.id.fecha_lugar);
          vLikeButton = (Button)  itemView.findViewById(R.id.like_button);
          vRelativeLayout = (RelativeLayout) itemView.findViewById(R.id.layout_cardview);
          vCardView = (CardView)itemView.findViewById(R.id.card_view);
  
          //Valores por defecto de los botones y del fondo en caso de no haber like ni foto
          vLikeButton.setBackgroundResource(R.drawable.button_like);
          vRelativeLayout.setBackgroundResource(R.color.fondo_card_view);
          vLikeButton.setOnClickListener(this);
          vCardView.setOnClickListener(this);
          vLikeButton.setTag("boton");
          vCardView.setTag("evento");
  
          this.eventoInfo = eventoInfo;
      }
  
  
      @SuppressWarnings("deprecation")
      @Override
      public void onClick(View v) {
          if(v.getTag().equals("boton")){
              likesManager = new LikesDDBB(this.eventoInfo.get(getPosition()).like, usuario,
                      vLikeButton, getPosition(), eventoInfo, paginaInicio);
              likesManager.execute();
          }else if(v.getTag().equals("evento")){
              Intent inicion = new Intent(paginaInicio,DetalleActivity.class);
  
              paginaInicio.startActivity(inicion);
          }
  
      }
  
  }
  
  //Para obtener la lista de eventos desde la clase PaginaInicioActivity
  public List&lt;EventoInfo&gt; getEventoInfo() {
      return eventoInfo;
  }
  
  public void setEventoInfo(List&lt;EventoInfo&gt; eventoInfo) {
      this.eventoInfo = eventoInfo;
  }
  
  }
  </code></pre>