使用Android Universal Image Loader和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
。
谢谢!
我相信错误是由于图像加载器的多个实例:
ImageLoader imageLoader = ImageLoader.getInstance();
尝试为适配器创建一个相同的实例。用其他类变量声明它。通过在onBindViewHolder()
中调用图像加载程序,您正在创建图像加载程序的多个实例。
您需要确保在应用程序中仅启动一次ImageLoader。创建一个类,并用Application扩展它,然后放入AndroidManifest.xml如下:
<application
android:name=".App"
.../>
应用程序类
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
// UNIVERSAL IMAGE LOADER SETUP
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.cacheOnDisk(true)
.cacheInMemory(true)
.imageScaleType(ImageScaleType.EXACTLY)
.displayer(new FadeInBitmapDisplayer(300))
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.memoryCache(new WeakMemoryCache())
.diskCacheSize(100 * 1024 * 1024)
.build();
ImageLoader.getInstance().init(config);
// END - UNIVERSAL IMAGE LOADER SETUP
}
}
对于您想知道的onBindViewHolder
:
@Override
public void onBindViewHolder(final CategoryHolder holder, final int i) {
holder.categoryImage.setImageBitmap(null);
if (mRow.get(i).getImage() != null && !mRow.get(i).getImage().equals("")) {
final File image = DiskCacheUtils.findInCache(mRow.get(i).getImage(), imageLoader.getDiskCache());
if (image!= null && image.exists()) {
Picasso.with(getActivity()).load(image).fit().centerCrop().into(holder.categoryImage);
} else {
imageLoader.loadImage(mRow.get(i).getImage(), new ImageLoadingListener() {
@Override
public void onLoadingStarted(String s, View view) {
holder.categoryImage.setImageBitmap(null);
}
@Override
public void onLoadingFailed(String s, View view, FailReason failReason) {
}
@Override
public void onLoadingComplete(String s, View view, final Bitmap bitmap) {
Picasso.with(getActivity()).load(s).fit().centerCrop().into(holder.categoryImage);
}
@Override
public void onLoadingCancelled(String s, View view) {
}
});
}
}else {
holder.categoryImage.setImageBitmap(null);
}
holder.categoryName.setText(mRow.get(i).getName().toUpperCase());
}
我正在为列表视图编写一个lazyload代码,在这个代码中,我得到了一个json格式的文本和图像url,并将它们放在列表视图中。 图像和文字都相应地显示为我想要的。 我面临的问题是,当列表向下或向上滚动时,视图的索引会受到干扰。 假设我的列表中有10个元素,图像可以横向预览。最初,我可以看到4个元素的onclick操作运行良好,但当我向下滚动并单击第7个元素时,索引会受到干扰,并导致空指针异常。
我试着把我的头绕到相对较新的img属性“加载”上。 我知道,如果img具有load=“lazy”属性,那么它会告诉支持该属性的浏览器,在接近视口时可以加载该属性。 那么为什么不总是设置loading=“lazy”?那些立即出现在屏幕上的图像无论如何都会被渲染,因为它们已经在视口中了。因此,在这种情况下,基本上忽略了load=“lazy”。 在这个演示https://mathiasbynens.be
我有一个数据表的问题-懒加载。我认为问题是在IdiomasBean.java(TableBean.java),如果我把: 我得到了正确的数据表,但是<代码>按排序、筛选和不起作用。 我得到:java。lang.NullPointerException这里是堆栈跟踪: 下面是代码的其余部分: 指数xhtml diomasBean.java 懒散的数据模型。JAVA IdiomasBo.java 习语
我正在使用volley向tmdb数据库发出RESTAPI请求,以加载有关电影的信息。回收器视图应显示缩略图图像海报。但它没有显示任何东西。我正在使用毕加索图书馆加载图像。图像链接构造得很好,我已经用log语句检查过了 主要活动。xml 列出项目布局。xml 主要活动 电影数据加载器
当我尝试将Image URL解析到ImageView中时,回收器视图不显示,活动为空。我正在使用Picasso将图像加载到适配器类中的onBinfViewHolder方法中。这是相关代码 代表: } RepRvAdapter: } 解析JSON数据的方法: 现在,我有一行解析图像URL的代码被注释掉了。行取消注释后,活动将不再显示。如何获取要在ImageView中解析和显示的图像url?我认为这可
使用指南 组件介绍 Lazyload 是 Vue 指令,使用前需要对指令进行注册 引入方式 import Vue from 'vue'; import Lazyload from 'vue-lazyload'; Vue.use(Lazyload, { lazyComponent: true, //失败时显示 (可以自定义) error: 'https://nuofe.nnte