Tôi đang cố gắng để tạo ra một ứng dụng tương tự như một: An app with some images and description (cardview) in a recyclerviewAsyncTask tải hình ảnh RecyclerView
đầu tiên ở tất cả i tải tất cả các thông tin cho CardView của tôi từ một cơ sở dữ liệu Tiêu đề của hình ảnh, mô tả và URL từ hình ảnh. Khi tôi đặt tất cả thông tin đó vào RecyclerView, (tiêu đề và mô tả) hiển thị chính xác, nhưng đối với hình ảnh tôi tạo một lớp AsyncTask để tải hình ảnh từ URL và cho phép người dùng không chờ đợi nhiều thời gian chờ ứng dụng để đáp ứng.
Nếu người dùng cuộn chậm hình ảnh được tải chính xác và tất cả đều ổn, nhưng nếu tôi cuộn nhanh đến tôi có một số vấn đề, ví dụ hình ảnh được hiển thị trong mục 3 chẳng hạn được hiển thị trong mục cuối cùng cho đến khi hình ảnh mục cuối cùng được nạp và làm mới ....
Dưới đây một số mã cho bộ chuyển đổi của tôi, nơi tôi tải hình ảnh:
@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());
}
}
}
Ở đây mã cho CargarImagen lớp:
//Clase para cargar imagenes con una tarea asíncrona desde un url de la imagen
public class CargarImagen extends AsyncTask<String, String, Boolean>{
//RelativeLayout donde se introduce la imagen de fondo
RelativeLayout relativeLayout=null;
//EventoInfo para obtener la url de la imagen
List<EventoInfo> 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<EventoInfo> 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;
}
}
}
Tôi có thể cung cấp cho bạn tệp .apk và bạn có thể thấy sự cố.
Cảm ơn bạn trước. :)
Đây mã đầy đủ của bộ chuyển đổi của tôi
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<ViewHolder>{
private static final int TYPE_EVENTO = 0;
private static final int TYPE_FOOTER = 1;
//lista de eventos
private List<EventoInfo> 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<EventoInfo> 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<EventoInfo> eventoInfo;
private String usuario;
private LikesDDBB likesManager;
private PaginaInicioActivity paginaInicio;
private CardView vCardView;
public EventosViewHolder(View itemView,List<EventoInfo> 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<EventoInfo> getEventoInfo() {
return eventoInfo;
}
public void setEventoInfo(List<EventoInfo> eventoInfo) {
this.eventoInfo = eventoInfo;
}
}
Tôi cho phép bạn ở đây tệp .apk https://mega.co.nz/#!Wc1hlagS!XMOMauYpbdk_UZBIswBgcltbRpwAc7VqaJmlS4JZ9FE trong ứng dụng Người dùng: bruno và Mật khẩu: 1234 – Bruno
Bạn phải hủy AsyncTask ở nơi thích hợp (bất cứ khi nào không cần kết quả). Ví dụ, sử dụng phương thức hủy bỏ của AsyncTask trong phương thức 'onDetachedFromWindow()' của Chế độ xem tùy chỉnh của bạn, nếu bạn có chế độ xem tùy chỉnh của riêng mình. –
[đây là giải pháp vấn đề của bạn] (https://www.youtube.com/watch?v=8MIfSxgsHIs&feature=youtu.be&list=PLWz5rJ2EKKc86y1CjAlexivfvOms6_0NC) –