使用 Android通用图像加载器 和 RecyclerView 异步加载图片时,我遇到了与其他人相同的错误,即图片混乱直到它们全部加载并缓存。
适配器的代码:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.media.Image;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
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.TextView;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.utils.MemoryCacheUtils;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import romina.theftest.connectivity.ImgDownloader;
/**
* Created by romin on 18/1/2016.
*/
public class ProductRecyclerViewAdapter extends RecyclerView.Adapter {
private List<Product> mValues;
private Context mContext;
private View.OnClickListener mListener;
// Allows to remember the last item shown on screen
private int lastPosition = -1;
private final String OLD_DOMAIN = "";
private final String NEW_DOMAIN = "";
public ProductRecyclerViewAdapter(Context mContext, View.OnClickListener mListener) {
this.mContext = mContext;
this.mListener = mListener;
}
public ProductRecyclerViewAdapter(List<Product> mValues, Context mContext, View.OnClickListener mListener) {
this(mContext, mListener);
this.mListener = mListener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.product_list_item, parent, false);
Log.d(ProductRecyclerViewAdapter.class.getSimpleName(), "onCreateViewHolder");
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ViewHolder actualViewHolder = (ViewHolder) holder;
actualViewHolder.mItem = mValues.get(position);
actualViewHolder.mIdView.setText("" + mValues.get(position).getName());
Log.d(ProductRecyclerViewAdapter.class.getSimpleName(), "onBindViewHolder pos " + position);
ImageLoader imageLoader = ImageLoader.getInstance(); // Get singleton instance
final String finalImgURL = mValues.get(position).getImgURL().toString().replaceAll(OLD_DOMAIN, NEW_DOMAIN);
imageLoader.displayImage(finalImgURL, actualViewHolder.mImgView);
setAnimation(actualViewHolder.mContentView, position);
}
public void setDataSet(List<Product> newValues) {
mValues = newValues;
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return mValues == null ? 0 : mValues.size();
}
/**
* Here is the key method to apply the animation
*/
private void setAnimation(View viewToAnimate, int position) {
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition) {
Animation animation = AnimationUtils.loadAnimation(mContext, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final ImageView mImgView;
public final TextView mContentView;
public Product mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.product_quantity_title);
mContentView = (TextView) view.findViewById(R.id.product_quantity_title);
mImgView = (ImageView) view.findViewById(R.id.product_quantity_image);
mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener) {
mListener.onClick(v);
}
}
});
}
@Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
我知道问题一定出在 onBindViewHolder
这个方法中,因为每次刷新视图都会调用它,但我没有正确地更新 ImageView
。
这与库无关。 在不缓存图像的情况下进行惰性加载时,也会发生相同的行为。错误是因为我不知道如何在 onBindViewHolder
中更新 ImageView
。
谢谢!