滚动时,在recyclerView中取消选中复选框

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滚动时,在recyclerView中取消选中复选框相关的知识,希望对你有一定的参考价值。

我有一个光标,它检索成分列表并填充适配器,然后将其分配给具有复选框的回收器视图。我得到的问题是,当我检查一组复选框并向下滚动时,从顶部选择的那些,取消选择,反之亦然,或者在某些情况下,如果我从顶部选择三个,从底部选择三个被选中。我需要确保,最初没有选择任何内容,即使我上下滚动,所选的选项应保持选中状态并需要跟踪。

这是可滚动的列表。

enter image description here

这是我的代码:

class RecipeDetailCursorAdapter extends CursorRecyclerViewAdapter<RecyclerView.ViewHolder> {

    private int mBrownColor;
    private int mGreenColor;
    private int mCheckItems;
    private ItemsCheckedCallback mCheckedCallback;

    RecipeDetailCursorAdapter(Context context, Cursor cursor, ItemsCheckedCallback callback) {
        super(context, cursor);
        mCheckedCallback = callback;
        mBrownColor = ContextCompat.getColor(mContext, R.color.colorTextBrown);
        mGreenColor = ContextCompat.getColor(mContext, R.color.colorTextGreen);
        mCheckItems = 0;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, Cursor cursor) {
        String taskName = cursor.getString(cursor.getColumnIndexOrThrow(MascotHelper.RecipeTask.NAME));
        ((RecipeTaskHolder) viewHolder).bindView(taskName);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recipe_task_item, parent, false);
        return new RecipeTaskHolder(v);
    }


    private class RecipeTaskHolder extends RecyclerView.ViewHolder
            implements SmoothCheckBox.OnCheckedChangeListener {

        SmoothCheckBox taskBox;
        TextView recipeComponentName;


        RecipeTaskHolder(View v) {
            super(v);
            taskBox = (SmoothCheckBox) v.findViewById(R.id.recipe_task_box);
            recipeComponentName = (TextView) v.findViewById(R.id.recipe_component_name);
            taskBox.setOnCheckedChangeListener(this);
        }


        void bindView(String task) {
            recipeComponentName.setText(task);
        }

        @Override
        public void onCheckedChanged(SmoothCheckBox smoothCheckBox, boolean b) {
            if (smoothCheckBox.isChecked()) {
                recipeComponentName.setTextColor(mBrownColor);
                mCheckItems++;
            } else {
                recipeComponentName.setTextColor(mGreenColor);
                mCheckItems--;
            }


            if (mCheckItems == getItemCount()) {
                //Toast.makeText(mContext, "All items are checked", Toast.LENGTH_SHORT).show();
                mCheckedCallback.onAllItemChecked(true);
            } else {
                mCheckedCallback.onAllItemChecked(false);
            }
        }
    }


    interface ItemsCheckedCallback {
        void onAllItemChecked(boolean status);
    }
}

任何想法或建议将不胜感激。

答案

在onBindView上使用下面的逻辑:

holder.attenCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (holder.attenCheckBox.isChecked())
                    dataModel.setChecked(true);
                else
                    dataModel.setChecked(false);
            }
        });

        if (dataModel.getChecked())
            holder.attenCheckBox.setChecked(true);
        else
            holder.attenCheckBox.setChecked(false);
        holder.checkboxLinearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (holder.attenCheckBox.isChecked())
                    holder.attenCheckBox.setChecked(false);
                else
                    holder.attenCheckBox.setChecked(true);
            }
        });

说明:

  • 每次向下或向上滚动时,Recyclerview都会膨胀。
  • 您需要在数据pojo中存储一个标志以跟踪检查状态
  • 使用setOnCheckedChangeListener的那面旗帜,你可以让你检查enable/disable。确保你在听众之后放置旗帜。
另一答案

RecyclerView在滚动时从布局中删除(循环)看不见的视图,这是recyclerView的基本行为,以减少内存使用。

如果一个带有复选框的视图被循环使用,则复选的复选框将被取消选中,如果它有一个监听器,则会调用该监听器。

您可以在回收时从视图中删除侦听器。只需覆盖onViewRecycled方法即可。

    @Override
    public void onViewRecycled(@NonNull MyViewHolder holder) {
        holder.checkBox.setOnCheckedChangeListener(null);
        super.onViewRecycled(holder);
    }

再次构建视图时,在滚动时,您的侦听器也将再次添加。

另一答案
@Override
public void onBindViewHolder(MyViewHolder holder,final int position) {
   final ClassName object = objectList.get(position);
    object.checkBox.setOnCheckedChangeListener(null);
    object.checkBox.setChecked(false);
    object.checkBox.setOnCheckedChangeListener(new android.widget.CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            object.setChecked(isChecked);
        }
    });
}

这会持续地绑定视图并保持您的检查位置,并在视图绑定时一次又一次地检查它们。

希望这对你有所帮助。

以上是关于滚动时,在recyclerView中取消选中复选框的主要内容,如果未能解决你的问题,请参考以下文章

取消选择并向下滚动后,列表视图中的复选框被选中。

滚动列表视图 BaseAdapter 上的复选框选中/未选中状态更改

如何在活动启动时在recyclerview中显示已选中的复选框(多对多关系)

滚动后未选中 ListView 适配器中的 Android 复选框

使用 listiview 取消选中 Onscroll 选中的复选框

当我取消选中自定义树视图中的子节点复选框时,如何取消选中所有父节点