在onBindViewHolder中调用notifyDataSetChanged

时间:2019-02-24 17:38:33

标签: android android-recyclerview picasso

一旦毕加索回调被触发,我试图在onBindViewHolder内创建一个notifyDataSetChanged,但是我总是遇到这个错误

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout

之所以需要这样做,是因为我使用的是StaggeredGridLayoutManager,因此在毕加索加载了不同大小的图像后,需要对recyclerview进行重新排序

我的实际代码是:

@Override
public void onBindViewHolder(filmsAdapter.ViewHolder holder, int position) {


    FilmInfo filmInfo = filmsList.get(position);

    Picasso.get()
            .load(filmInfo.GetPreviewImageUrl())
            .placeholder(R.drawable.ic_launcher)
            .into(holder.getFilmItemIcon(), new Callback() {
                @Override
                public void onSuccess() {
                    notifyDataSetChanged();
                }

                @Override
                public void onError(Exception e) {

                }
            });

        holder.getItemContainer().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(mContext, MainActivity.class);
            intent.putExtra("filmInfo", filmInfo);
            view.getContext().startActivity(intent);
        }
    });


}

1 个答案:

答案 0 :(得分:1)

关于此问题,您可以使用ReclyclerView.isComputingLayout()来检查RecyclerView是否仍在计算布局。

但是,由于Picasso异步加载图像,因此将生成无限循环。当Picasso.onSuccess触发notifyDataSetChanged时,将再次调用onBindViewHolder,依此类推。

唯一的解决方案是,如果您知道必须处理多少个条目,则可以跟踪必须加载多少个图像或使用信号量,但是如果列表中的项目数未定义,则不会如此简单,因为每次用户滚动RecyclerView都会调用onBindViewHolder。

因此,总体问题是Picasso.onSuccess将调用notifyDataSetChanged,而notifyDataSetChanged将再次调用onBindViewHolder,这将再次触发Picasso。