Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
862 views
in Technique[技术] by (71.8m points)

java - 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.

enter image description here

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

RecyclerView removes (recycles) the unseen views from the layout on scrolling, this is the basic behavior of recyclerView in order to reduce memory use.

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.

    @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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...