简体   繁体   English

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

[英]checkboxes gets unchecked in recyclerView upon scrolling

I have a cursor which retrieves a list of ingredients and populates an adapter, which is then assigned to a recycler View having checkboxes.我有一个游标,它检索成分列表并填充一个适配器,然后将其分配给具有复选框的回收器视图。 The problem I've got is that, when I check a set of checkboxes and scroll down, the ones selected from the top, get deselected and vice versa, or in some instances, if I select three from the top, three from the bottom get selected.我遇到的问题是,当我检查一组复选框并向下滚动时,从顶部选择的那些被取消选择,反之亦然,或者在某些情况下,如果我从顶部选择三个,从底部选择三个被选中。 I need to make sure that, initially nothing is selected, and even if I scroll up and down, the ones selected should remain selected and need to keep track of.我需要确保最初没有选择任何内容,即使我上下滚动,所选的内容也应保持选中状态并需要跟踪。

Here is the list which is scrolable.这是可滚动的列表。

在此处输入图片说明

Here is my code:这是我的代码:

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);
    }
}

Any ideas or suggestions would be appreciated.任何想法或建议将不胜感激。

RecyclerView removes (recycles) the unseen views from the layout on scrolling, this is the basic behavior of recyclerView in order to reduce memory use. RecyclerView 在滚动时从布局中移除(回收)看不见的视图,这是 recyclerView 的基本行为,以减少内存使用。

When a view with a checkbox is recycled, a checked checkbox gets unchecked and if it has a listener, the listener gets called.当带有复选框的视图被回收时,选中的复选框将被取消选中,如果它有一个侦听器,则调用该侦听器。

You can remove the listener from the view when it is recycled.您可以在回收时从视图中删除侦听器。 Just override the onViewRecycled method.只需覆盖 onViewRecycled 方法。

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

When the view is constructed again, while scrolling, your listener will also be added again.再次构建视图时,在滚动时,您的侦听器也将再次添加。

use logic below on onBindView:在 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);
            }
        });

Explanation:解释:

  • Recycle view inflate eveytime when you scroll down or up.当您向下或向上滚动时,回收视图会膨胀 eveytime。
  • you need to store a flag in the data pojo to keep track of check status您需要在数据 pojo 中存储一个标志以跟踪检查状态
  • using that flag with setOnCheckedChangeListener will enable you to have you checked enable/disable .将该标志与setOnCheckedChangeListener一起使用将使您能够检查enable/disable Make sure you put flag after listener.确保在听众之后放置标志。
@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);
        }
    });
}

This continuously binds the views and keeps your checked positions and keeps checking them again and again when ever the view binds. 这会持续地绑定视图并保持您的检查位置,并在视图绑定时一次又一次地检查它们。

Hope this helps you. 希望这对你有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM