图像无法从recyclerview中的URL正确加载

时间:2016-01-17 03:59:25

标签: android android-recyclerview

我有Recyclerview GridLayoutManagerRecyclerview中的列表项会从包含JSONName的网址中加载简单Image URL。我已按照this教程加载了收到的网址中的asynchronously图片。当我的应用第一次加载时,这就是我所看到的。

When I load the app for the first time

当我浏览另一项活动并回来时,这就是我所看到的。 When I browse other activities and come back

这是Adapter

Recyclerview
public class CategoriesAdapter extends RecyclerView.Adapter<CategoriesViewHolder> {

    private LayoutInflater inflater;
    private CategoriesViewHolder viewHolder;
    private ArrayList<Categories> categoriesList = new ArrayList<>();
    private VolleySingleton volleySingleton;
    private ImageLoader imageLoader;

    public CategoriesAdapter(Context context){
        inflater = LayoutInflater.from(context);
        volleySingleton = VolleySingleton.getsInstance();
        imageLoader = volleySingleton.getImageLoader();
    }

    public void setCategoriesList(ArrayList<Categories> categoriesList){
        this.categoriesList = categoriesList;
        notifyItemRangeChanged(0, categoriesList.size());
    }

    @Override
    public CategoriesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.categories_list, parent, false);
        viewHolder = new CategoriesViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(CategoriesViewHolder holder, int position) {
        Categories current = categoriesList.get(position);
        viewHolder.categoryName.setText(current.categoryName);

        imageLoader.get(current.icon_url, new ImageLoader.ImageListener() {
            @Override
            public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                viewHolder.categoryIcon.setImageBitmap(response.getBitmap());
            }

            @Override
            public void onErrorResponse(VolleyError error) {
                //viewHolder.contactIcon.setImageResource(R.drawable.image);
            }
        });
    }

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

这是我的VolleySingleton班级

public class VolleySingleton {

    private static VolleySingleton sInstance = null;
    private RequestQueue mRequestQueue;
    private ImageLoader imageLoader;

    private VolleySingleton(){
        mRequestQueue = Volley.newRequestQueue(MyApplication.getsInstance());
        imageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
            private LruCache<String, Bitmap> cache = new LruCache<>((int) (Runtime.getRuntime().maxMemory()/1024)/8);
            @Override
            public Bitmap getBitmap(String url) {
                return cache.get(url);
            }

            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                cache.put(url, bitmap);
            }
        });
    }

    public static VolleySingleton getsInstance(){
        if(sInstance==null){
            sInstance = new VolleySingleton();
        }
        return sInstance;
    }

    public RequestQueue getmRequestQueue(){
        return mRequestQueue;
    }

    public ImageLoader getImageLoader(){
        return imageLoader;
    }

}

2 个答案:

答案 0 :(得分:0)

我个人建议您使用此库Picasso,而不是自己完成所有繁重的工作。

加载图片就像这样简单,

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

答案 1 :(得分:0)

很难说为什么你会看到你所看到的东西,但是有些问题使得这种方法不太可用。

onBindViewHolder

  1. 检查您是否已有位图(例如,在内存缓存中)。如果有,请致电ImageView.setImageBitmap
  2. 如果没有,请从磁盘或网络异步加载。加载完成后,不是直接设置视图,而是更新内存缓存并向适配器发出数据集已更改的信号(例如,通过BaseAdapter.notifyDataSetChanged)。理想情况下,您只想更新已更改的视图,而RecyclerView.Adapter确实允许通过notifyItemChanged进行更新。两者都是&#34;通知&#34;方法将导致onBindViewHolder被调用,这一次,第1步应该会成功。
  3. 据说,使用第三方库,按照前一作者的建议(我偏向Glide)。它使事情变得相当容易,并且你不太可能在脚下射击自己 - 并且实现自定义图像加载/缓存存在许多问题。