【问题标题】:RecyclerView with checkbox checked/unchecked automatically when I am scrolling滚动时自动选中/取消选中复选框的 RecyclerView
【发布时间】:2018-01-27 08:59:13
【问题描述】:

这是我的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
    }
}

【问题讨论】:

    标签: android android-recyclerview android-viewholder


    【解决方案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) { }
      }
    
      ...
    
    }
    

    【讨论】:

    • 是的,这就是我要发布的内容。尝试这个。好答案
    • 很好的答案,但是当我再次向上滚动时,一些复选框被选中
    • 我不能做 checkBox.setOnClickListener(new View.OnClickListener()) 只有 holder.checkBox.setOnClickListener(new View.OnClickListener()) 我能做
    • 并且还可以告诉我如何在我的代码中只获取选中的复选框项目
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 它不工作
    猜你喜欢
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    相关资源
    最近更新 更多