【问题标题】:RecyclerView doesn't update UI on Android 5.1.1RecyclerView 不会在 Android 5.1.1 上更新 UI
【发布时间】:2018-04-20 13:26:05
【问题描述】:

我有一个问题,只能在 Android 5.1.1 上重现,而在 5.1 上的设备很少。在其余版本上工作正常。

Recycler 视图具有 onClick 侦听器,我尝试将 View Visibility 从 GONE 更新为 VISIBLE 或相反。单击项目后,UI 上没有任何变化。 注意:如果我关闭 (BackButton) 片段并再次打开 - UI 将会更新。即使在按下后退按钮后,我也看到 UI 在销毁前更新了几毫秒。

我尝试通知所有适配器、当前项目、使 itemView 无效、swap() 并再次设置适配器但没有成功。 所有方法 setVisibility()、onClick、Callbacks、BindView 都被成功调用(调试器)。

public class PhotoGalleryAdapter extends RecyclerView.Adapter<PhotoGalleryAdapter.PhotoHolder> {

    private Context context;
    private List<String> photos;
    private View.OnClickListener listener;

    public PhotoGalleryAdapter(Context context, List<String> photos, View.OnClickListener listener) {
        this.context = context;
        this.photos = photos;
        this.listener = listener;
    }

    @Override
    public PhotoGalleryAdapter.PhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_photo, parent, false);
        return new PhotoHolder(v, listener);
    }

    @Override
    public void onBindViewHolder(final PhotoGalleryAdapter.PhotoHolder holder, int position) {
        String photoPath = photos.get(position);
        Glide.with(context)
                .load(photoPath)
                .thumbnail(0.1f)
                .into(holder.image);

        if (Utils.getSelectedPhotos().contains(photoPath)) {
            DrawableCompat.setTint(holder.selection.getDrawable(), ContextCompat.getColor(context, R.color.white));
            holder.selection.setVisibility(View.VISIBLE);
        } else {
            holder.selection.setVisibility(View.GONE);
        }
    }

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

    public void updateDataSet(List<String> photos) {
        if (!photos.equals(this.photos)) {
            this.photos.clear();
            this.photos.addAll(photos);
            notifyDataSetChanged();
        }
    }

    class PhotoHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        @BindView(R.id.imageView) AppCompatImageView image;
        @BindView(R.id.selectionState) AppCompatImageView selection;

        private View.OnClickListener listener;

        PhotoHolder(View view, View.OnClickListener listener) {
            super(view);
            ButterKnife.bind(this, view);
            view.setOnClickListener(this);
            this.listener = listener;
        }

        @Override
        public void onClick(View view) {
           if (Utils.getSelectedPhotos().contains(photos.get(getAdapterPosition()))) {
                selection.setVisibility(View.GONE);
                Utils.getSelectedPhotos().remove(photos.get(getAdapterPosition()));
            } else {
                Utils.getSelectedPhotos().add(photos.get(getAdapterPosition()));
                DrawableCompat.setTint(selection.getDrawable(), ContextCompat.getColor(context, R.color.white));
                selection.setVisibility(View.VISIBLE);
            }
            listener.onClick(view);
        }
    }
}

关于回调:

 @Override public void onClick(View view) {
     callbacks.onPhotoSelected(Utils.getSelectedPhotos().size());
     adapter.notifyDataSetChanged(); }

【问题讨论】:

  • 您的支持库是最新的吗?
  • @TylerPfaff 是的,supportVersion = '27.0.0'
  • @ArsenBoikanych 有没有想过解决这个问题?

标签: android android-recyclerview visibility


【解决方案1】:

根据您的PhotoGalleryAdapter

public void updateDataSet(List<String> photos) {
    if (!photos.equals(this.photos)) {
        this.photos.clear();
        this.photos.addAll(photos);
        notifyDataSetChanged();
    }
}

而你使用

if (Utils.getSelectedPhotos().contains(photoPath)) {
        DrawableCompat.setTint(holder.selection.getDrawable(), ContextCompat.getColor(context, R.color.white));
        holder.selection.setVisibility(View.VISIBLE);
} else {
        holder.selection.setVisibility(View.GONE);
}

Utils.getSelectedPhotos() 这一行没有更新。

你的问题是callbacks.onPhotoSelected(Utils.getSelectedPhotos().size());

您可以使用updateDataSet 更新用户界面。

当你点击时。你可以像这样使用。

Utils.setSelectedPhotos(yourList);
adapter.updateDataSet(yourList);

编辑

您应该先更新您的列表,然后使用notifyDataSetChanged

所以你的列表没有更新,你应该检查一下。

【讨论】:

  • 不工作。 notifyDataSetChanged() 工作正常,但 UI (setVisibilty) 仍然无法工作。
  • 你应该检查你自己的代码。callbacks.onPhotoSelected(Utils.getSelectedPhotos().size());
  • 这段代码只返回同步列表。我尝试使用具有相同结果的本地(非静态)。
  • 祝你好运。@ArsenBoikanych
【解决方案2】:

更新解决方案:将onClick改为:

     @Override
            public void onClick(View view) {
               if (Utils.getSelectedPhotos().contains(photos.get(getAdapterPosition()))) {
                    Utils.getSelectedPhotos().remove(photos.get(getAdapterPosition()));
                } else {
                    Utils.getSelectedPhotos().add(photos.get(getAdapterPosition()));
                }
                notifyDataSetChanged();
                listener.onClick(view);
            }

效果很好,仅适用于 LinearLayoutManager。仍然不适用于 GridLayoutManager。 因此,在调用 setVisibility() 两次之后,Android 的工作无法预测。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多