在我滚动时自动选中/取消选中复选框的RecyclerView

时间:2018-01-27 08:59:14

标签: android android-recyclerview android-viewholder

这是我的QuestionHolder

 private class QuestionHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    private JSONObject question;
    private CheckBox checkBox;
    private TextView question_txt;
    public QuestionHolder(final LayoutInflater inflater, ViewGroup parent) {
        super(inflater.inflate(R.layout.question_item, parent, false));

        checkBox  = (CheckBox) itemView.findViewById(R.id.question_checkbox);

        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //try {
                    //Toast.makeText(getActivity(), "ID: " + question.get("_id"), Toast.LENGTH_SHORT).show();
                //} catch (JSONException e) { }
                // TODO: If this was checked then add the question's id to the answered list
            }
        });
        question_txt = (TextView) itemView.findViewById(R.id.question);
        itemView.setOnClickListener(this);
    }

这里我绑定了questiontxt

public void bind(JSONObject question) {
  this.question = question;
  try {
    question_txt.setText(question.getString("_question"));
  } catch (JSONException je) { }
}

@Override
public void onClick(View v) {
  // TODO: If this was checked then add the question's id to the answered list
}
}

这是我的适配器扩展QuestionHolder

private class QuestionAdapter extends RecyclerView.Adapter<QuestionHolder> {

    private JSONArray questions;

    public QuestionAdapter(JSONArray questions) {
        this.questions = questions;
    }

    @Override
    public QuestionHolder onCreateViewHolder(ViewGroup parent, int viewType) 
{
        return new QuestionHolder(LayoutInflater.from(getActivity()), parent);
    }

这是onBindViewHolder

@Override
public void onBindViewHolder(QuestionHolder holder, int position) {
  try {
    final JSONObject question = questions.getJSONObject(position);
    holder.bind(question);
  } catch (JSONException je) { }
}

@Override
public int getItemCount() {
  return questions.length();
}
}

这是QuestionHolder

private class QuestionHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    private JSONObject question;
    private CheckBox checkBox;
    private TextView question_txt;
    public QuestionHolder(final LayoutInflater inflater, ViewGroup parent) {
        super(inflater.inflate(R.layout.question_item, parent, false));

        checkBox  = (CheckBox) itemView.findViewById(R.id.question_checkbox);

        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //try {
                    //Toast.makeText(getActivity(), "ID: " + question.get("_id"), Toast.LENGTH_SHORT).show();
                //} catch (JSONException e) { }
                // TODO: If this was checked then add the question's id to the answered list
            }
        });
        question_txt = (TextView) itemView.findViewById(R.id.question);
        itemView.setOnClickListener(this);
    }

    public void bind(JSONObject question) {
        this.question = question;
        try {
            question_txt.setText(question.getString("_question"));
        } catch (JSONException je) { }
    }

    @Override
    public void onClick(View v) {
        // TODO: If this was checked then add the question's id to the answered list
    }
}

2 个答案:

答案 0 :(得分:1)

这是因为滚动时您的ViewHolder会被回收。因此,您需要为每个项目位置保持CheckBox的状态。您可以使用SparseBooleanArray来处理此问题。

您可以这样做:

private class QuestionAdapter extends RecyclerView.Adapter<QuestionHolder> {

  SparseBooleanArray checkedItems = new SparseBooleanArray();

  ...

  @Override
  public void onBindViewHolder(QuestionHolder holder, int position) {
    try {
      final JSONObject question = questions.getJSONObject(position);

      // Remember to change access modifier of checkBox in your ViewHolder
      // Get the state from checkedItems. If no previous value, it will return false.
      holder.checkBox.setChecked(checkedItems.get(position));

      // This is a sample. Do not use create listener here.
      checkBox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          // save the check state
          checkedItems.put(position, true);
        }

      holder.bind(question);
    } catch (JSONException je) { }
  }

  ...

}

答案 1 :(得分:1)

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

因此,当带有“复选框”的视图被“回收”时,已选中复选框将被取消选中,并且如果它具有侦听器,则会调用该侦听器。

可以在视图回收后将其从视图中删除。只需重写onViewRecycled方法即可。

 @Override
    public void onViewRecycled(@NonNull MyViewHolder holder) {
        if (holder.checkBox != null) {
            holder.checkBox.setOnClickListener(null);
        }
        super.onViewRecycled(holder);
    }

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