【问题标题】:checkboxes gets unchecked in recyclerView upon scrolling滚动时复选框在 recyclerView 中未选中
【发布时间】:2019-12-09 20:53:02
【问题描述】:

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

这是可滚动的列表。

这是我的代码:

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

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

【问题讨论】:

    标签: java android


    【解决方案1】:

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

    当一个带有复选框的视图被回收时,一个选中的复选框会被取消选中,如果它有一个监听器,监听器就会被调用。

    当监听器被回收时,你可以从视图中移除它。只需覆盖 onViewRecycled 方法。

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

    当视图再次构建时,在滚动的同时,你的监听器也会被再次添加。

    【讨论】:

      【解决方案2】:

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

      解释:

      • 当您向下或向上滚动时,循环视图每次都会膨胀。
      • 您需要在数据 pojo 中存储一个标志以跟踪检查状态
      • 将该标志与setOnCheckedChangeListener 一起使用将使您能够检查enable/disable。确保在侦听器之后放置标志。

      【讨论】:

      • 请解释一下它的作用以及它可能会做出哪些改变以澄清您的答案,在此先感谢!
      • 当您向下或向上滚动时,每一次循环视图都会膨胀......您需要在数据 pojo 中存储一个标志以跟踪检查状态,使用该标志与 setOnCheckedChangeListener 将使您能够拥有您检查启用/禁用。确保在侦听器@KingReload 之后放置标志 .. 请标记检查是否有效
      • 感谢您的回答,但请将其编辑为您的回答 :) 其他用户会更容易阅读;)
      • 希望现在可以理解@KingReload
      猜你喜欢
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      • 2018-06-09
      相关资源
      最近更新 更多