在android中,选中RecyclerView中的Checkbox,会自动选中其他复选框

时间:2019-01-18 12:26:33

标签: java android checkbox android-recyclerview

我需要在android回收器视图的每个条目中使用复选框来选择一些项目。一旦我选中了位置0的复选框,滚动时每个第9个位置的复选框也会自动选中。

如何克服这个问题?

//在我的适配器类中

_._2

4 个答案:

答案 0 :(得分:3)

使用数组保存项目的状态

在适配器中,使用Map或SparseBooleanArray(与map类似,但它是int和boolean的键值对)将所有项目的状态存储在项目列表中,然后在切换检查状态时使用键和值进行比较

在适配器中创建一个SparseBooleanArray

// sparse boolean array for checking the state of the items

    private SparseBooleanArray itemStateArray= new SparseBooleanArray();

然后在项目点击处理程序onClick()中使用itemStateArray中的项目状态在切换之前进行检查,这是一个示例

        @Override
        public void onClick(View v) {
            int adapterPosition = getAdapterPosition();
            if (!itemStateArray.get(adapterPosition, false)) {
                mCheckedTextView.setChecked(true);
                itemStateArray.put(adapterPosition, true);
            }
            else  {
                mCheckedTextView.setChecked(false);
                itemStateArray.put(adapterPosition, false);
            }
        }

另外,使用稀疏布尔数组设置绑定视图时的检查状态

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bind(position);
}

@Override
public int getItemCount() {
    if (items == null) {
        return 0;
    }
    return items.size();
}

 void loadItems(List<Model> tournaments) {
    this.items = tournaments;
    notifyDataSetChanged();
}


class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    CheckedTextView mCheckedTextView;

    ViewHolder(View itemView) {
        super(itemView);
        mCheckedTextView = (CheckedTextView) itemView.findViewById(R.id.checked_text_view);
        itemView.setOnClickListener(this);
    }

    void bind(int position) {
        // use the sparse boolean array to check
        if (!itemStateArray.get(position, false)) {
            mCheckedTextView.setChecked(false);}
        else {
            mCheckedTextView.setChecked(true);
        }
    }

答案 1 :(得分:1)

您正面临此问题,因为RecyclerView使用ViewHolder模式,通过该模式可以重用子视图并减少内存消耗。

您可以关注此link



您可以按照以下简单步骤进行操作。

1)在数据源中添加一个布尔值,即数据/模型类的列表。
(此布尔值将存储复选框的当前状态)

2)在复选框的onClick事件中,为呈现的数据模型切换该布尔值,并调用notifyDataSetChanged。
(在此不要使用onCheckedChanged

3)在渲染放置条件时,是否基于该布尔值将复选框标记为选中还是未选中。

答案 2 :(得分:1)

如果您可以在一个匿名实现中使用position,则表示它是final。就像里面的复选框侦听器一样。

final position将导致数据和UI之间存在差异,因为将不会再次对其进行定义。 此时,应该在onBindViewHolder方法上做些细说,这比我的方法有更好的解释。

要获得最终排名,您可以使用:

holder.getAdapterPosition()

您不必担心持有人是否是决赛,因为持有人是该行,并且不会再次被实例化。如果适配器回收了它,那就没问题了。

答案 3 :(得分:1)

当我在OnBindViewHolder中分配了checkedChange侦听器时,我遇到了问题,因此在回收时会多次被调用。对我有用的是在viewHolder create方法中定义回调和侦听器。

public class CheckBoxHolder : RecyclerView.ViewHolder
    {
        public TextView line, destination, twd;
        public ImageView icon;
        public LinearLayout lineParent;
        public CheckBox checkBox;
        public CheckBoxHolder(View view, Action<int, CompoundButton.CheckedChangeEventArgs> listener) : base(view)
        {
            checkBox = view.FindViewById<CheckBox>(Resource.Id.check_checkBox);

            twd = view.FindViewById<TextView>(Resource.Id.check_twd);
            destination = view.FindViewById<TextView>(Resource.Id.check_dest);
            line = view.FindViewById<TextView>(Resource.Id.check_line);
            lineParent = view.FindViewById<LinearLayout>(Resource.Id.check_line_parent);
            icon = view.FindViewById<ImageView>(Resource.Id.check_icon); 
            view.Click += (sender, e) => {
                checkBox.Checked = !checkBox.Checked;
            };
            checkBox.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) => listener(base.Position, e);
        }
    }

这是xamarin的C#代码,但该概念应适用于您的问题。