选择一个RadioButton值并向后滚动以删除RecyclerView中的选定值

时间:2015-12-14 12:17:26

标签: android android-recyclerview

在我的申请中,我在Unity的帮助下显示了20个多项选择题。

如果我更改了第一个RecyclerView的值并向下滚动,请再次向上滚动,删除RadioGroup中的所选值,同时我还希望进一步使用该选定的RecycelarView值,我是还检查了link1,但我没有理解他在做什么。

以下是我的示例代码段,如果您需要任何说明,请告诉我。

RadioButton

10 个答案:

答案 0 :(得分:4)

onBindViewHolder()修改为此

public void onBindViewHolder(ViewHolder viewHolder, int position) {

        final int pos = position;

        viewHolder.tvQuestionNumber.setText(stList.get(position).getQuestionNumber() + "");

        viewHolder.tvQuestion.setText(stList.get(position).getQuestion());

        viewHolder.rbAns1.setText(stList.get(position).getAnswer1());

        viewHolder.rbAns2.setText(stList.get(position).getAnswer2());

        viewHolder.rbAns3.setText(stList.get(position).getAnswer3());

        viewHolder.rbAns4.setText(stList.get(position).getAnswer4());

        viewHolder.rbAns5.setText(stList.get(position).getAnswer5());

        //viewHolder.rgAnswers.clearCheck();

        viewHolder.rgAnswers.setTag(position);


        Log.v("select" + position, stList.get(position).getSelectedRadioButtonId() + "");

        viewHolder.rgAnswers.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // TODO Auto-generated method stub
                int radioButtonID = group.getCheckedRadioButtonId();
                View radioButton = group.findViewById(radioButtonID);
                int clickedPos = (Integer) group.getTag();


               stList.get(clickedPos).setSelectedRadioButtonId(radioButtonID);

               // if you want to get selected button's info such as tag, text... etc.
                RadioButton radioButton = (RadioButton) viewHolder.itemView.findViewById(radioButtonID);

                if(radioButton != null) {
                    String customTag = radioButton.getTag().toString();
                    stList.get(clickedPos).setCustomTag(customTag);
                }


                Log.v("hello" + clickedPos, stList.get(clickedPos).getSelectedRadioButtonId() + "");
            }
        });

        viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId());

    }

它应该工作。如有任何问题,请告诉我。

答案 1 :(得分:4)

出现此问题的原因是RecyclerView或Android SDK中的某个位置存在错误。无论如何,我接受了另一个SO问题的建议 - onCheckedChanged called automatically

对于RadioGroup,它会有所不同。有两种方法可以解决。我推荐第一个,因为它是即插即用的。

  1. OnCheckedChangeListener上设置RadioGroup

    mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            if(checkedId == -1) {
                Log.v("onCheck", "Android bug since RadioButton doesn't get unchecked normally!");
            }
            else {
                Log.v("onCheck", "Valid click. By user");
                mMyListObjectArr[position].setChecked(checkedId);
            }
        }
    });
    
  2. 或在onCheckedChangeListener内的所有RadioButton上设置RadioGroup

    CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(buttonView.isPressed()) {
                Log.v("onCheck", position + ", valid click by user");
                mMyListObjectArr[position].setChecked(buttonView.getId());
            }
            else {
                Log.v("onCheck", "Android bug");
            }
        }
    };
    mRadioButton1.setOnCheckedChangeListener(onCheckedChangeListener);
    mRadioButton2.setOnCheckedChangeListener(onCheckedChangeListener);
    

答案 2 :(得分:3)

你可以这样做.....

在bean类中添加一个字段

String final_answer;
public String getFinalAnswer(){
  return final_answer;
}

public void setFinalAnswer(String final_answer){
  this.final_answer = final_answer;
}
适配器中的

.....

public void onBindViewHolder(final ViewHolder viewHolder, final int position) {

    final Student student = stList.get(position);

    viewHolder.tvQuestionNumber.setText(student.getQuestionNumber());

    viewHolder.tvQuestion.setText(student.getQuestion());

    viewHolder.rbAns1.setText(student.getAnswer1());

    viewHolder.rbAns2.setText(student.getAnswer2());

    viewHolder.rbAns3.setText(student.getAnswer3());

    viewHolder.rbAns4.setText(student.getAnswer4());

    viewHolder.rbAns5.setText(student.getAnswer4());

    viewHolder.rgAnswers.clearCheck();

   if(student.getSelectedRadioButtonId()!=null)
     viewHolder.rgAnswers.check(student.getSelectedRadioButtonId());
   else
     viewHolder.rgAnswers.clearCheck();

    viewHolder.rgAnswers.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
          if(checkedId != -1){
            student.setSelectedRadioButtonId(checkedId);
            RadioButton rb = (RadioButton)viewHolder.rgAnswers.
                                  findViewById(checkedId);

            student.setFinalAnswer(rb.getText);
            stList.get(position) = student;
          }
        }
    });
}

最终获得选定的答案...将此代码写入主要活动

  public void getSelectedAnswers(){

       for(int i=0;i<slist.length;i++){
          //get selected answer
          Log.i("answer",slist.get(i).getFinalAnswer());
       }
    }

答案 3 :(得分:3)

我根据您的要求创建了一个示例代码。

首先我们必须按如下方式创建xml:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerViewAppList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>

然后我们将创建一个如下界面

public interface OnOptionSelected {
public void onOptionSelected(int position,int itemSelected);
}

然后我们将按如下方式创建模型类:

public class QuestionModel {

private String question;
private int seleectedAnswerPosition;
private boolean op1Sel,op2Sel,op3Sel; // options 

public boolean isOp1Sel() {
    return op1Sel;
   }

public void setOp1Sel(boolean op1Sel) {
    this.op1Sel = op1Sel;
    if(op1Sel){ // To make sure only one option is selected at a time
        setOp2Sel(false);
        setOp3Sel(false);
    }
   }

    public boolean isOp2Sel() {
      return op2Sel;
   }

   public void setOp2Sel(boolean op2Sel) {
    this.op2Sel = op2Sel;
    if(op2Sel){
        setOp1Sel(false);
        setOp3Sel(false);
     }
      }

 public boolean isOp3Sel() {
    return op3Sel;
     }

 public void setOp3Sel(boolean op3Sel) {
    this.op3Sel = op3Sel;
    if(op3Sel){
        setOp2Sel(false);
        setOp1Sel(false);
     }
    }

    public int getSeleectedAnswerPosition() {
    return seleectedAnswerPosition;
    }

  public void setSeleectedAnswerPosition(int seleectedAnswerPosition) {
    this.seleectedAnswerPosition = seleectedAnswerPosition;
   }

  public String getQuestion() {
    return question;
  }
 public void setQuestion(String question) {
    this.question = question;
  }
     } 

然后我们将为行创建视图:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/question"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

    <RadioButton
        android:id="@+id/radoptionOne"
        android:text="May Be"
        android:checked="false"
        android:saveEnabled="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <RadioButton
        android:checked="false"
        android:id="@+id/radoptionTwo"
        android:text="NO"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <RadioButton
        android:checked="false"
        android:id="@+id/radoptionThree"
        android:text="Yes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
   </LinearLayout>

适配器类如下:

 public class QuestionAdapter extends      RecyclerView.Adapter<QuestionAdapter.ViewHolder> {

   private List<QuestionModel> questionModels;


public void setOnOptionSelected(OnOptionSelected onOptionSelected) {
    this.onOptionSelected = onOptionSelected;
}

private OnOptionSelected onOptionSelected;


public List<QuestionModel> getQuestionModels() {
    return questionModels;
}

public void setQuestionModels(List<QuestionModel> questionModels) {
    this.questionModels = questionModels;
}

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView question;
    RadioGroup radioGroup;
    RadioButton op1, op2, op3;

    ViewHolder(View view) {
        super(view);
        question = (TextView) view.findViewById(R.id.question);
        //radioGroup=(RadioGroup)view.findViewById(R.id.radGroup);
        op1 = (RadioButton) view.findViewById(R.id.radoptionOne);
        op2 = (RadioButton) view.findViewById(R.id.radoptionTwo);
        op3 = (RadioButton) view.findViewById(R.id.radoptionThree);
        op1.setOnClickListener(this);
        op2.setOnClickListener(this);
        op3.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.radoptionOne:
                onOptionSelected.onOptionSelected(getAdapterPosition(), 1);
                break;

            case R.id.radoptionTwo:
                onOptionSelected.onOptionSelected(getAdapterPosition(), 2);
                break;

            case R.id.radoptionThree:
                onOptionSelected.onOptionSelected(getAdapterPosition(), 3);
                break;
        }
    }
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v;
    // create a normal view
    v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.row_view, parent, false);
    return new ViewHolder(v);

}

@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
    viewHolder.question.setText(questionModels.get(position).getQuestion());

    Log.e("POSITION" + position, "1" + questionModels.get(position).isOp1Sel());

    Log.e("POSITION" + position, "2" + questionModels.get(position).isOp2Sel());
    Log.e("POSITION" + position, "3" + questionModels.get(position).isOp3Sel());


    viewHolder.op1.setChecked(questionModels.get(position).isOp1Sel());
    viewHolder.op2.setChecked(questionModels.get(position).isOp2Sel());
    viewHolder.op3.setChecked(questionModels.get(position).isOp3Sel());


}

@Override
public int getItemCount() {
    if (questionModels != null) {
        return questionModels.size();
    }
    return 0;
}
}

然后是Activity类:

public class MainActivity extends Activity implements OnOptionSelected{

private RecyclerView mRecyclerView;
private List<QuestionModel> questionModels;
private  QuestionAdapter questionAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mRecyclerView =(RecyclerView)findViewById(R.id.recyclerViewAppList);
    mRecyclerView.setHasFixedSize(true);
    questionModels=new ArrayList<QuestionModel>();
    for (int i=0;i<20;i++)
    {
        QuestionModel questionModel=new QuestionModel();
        questionModel.setQuestion("Question " + (i + 1));
        questionModels.add(questionModel);
    }
    questionAdapter =new QuestionAdapter();
    questionAdapter.setOnOptionSelected(this);
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    questionAdapter.setQuestionModels(questionModels);
    mRecyclerView.setLayoutManager(layoutManager);
    mRecyclerView.setAdapter(questionAdapter);
}


@Override
public void onOptionSelected(int position, int itemSelected) {
    questionModels.get(position).setSeleectedAnswerPosition(itemSelected);
    switch (itemSelected){
        case 1:
            questionModels.get(position).setOp1Sel(true);
            break;

        case 2:
            questionModels.get(position).setOp2Sel(true);
            break;
        case 3:
            ((QuestionModel)questionModels.get(position)).setOp3Sel(true);
            break;
    }
    questionAdapter.setQuestionModels(questionModels);
    questionAdapter.notifyDataSetChanged();
   // mRecyclerView.setAdapter(questionAdapter);

}
 }

我尝试使用Radiogroup解决方案,但它无法正常工作(有时保留旧值)。然后我改变了模型类中选择选项的方式。

sample

答案 4 :(得分:0)

问题在于回收者视图是回收(如名称所示)您的观点。

系统会在达到该金额后创建一定数量的ViewHolders来填充您的屏幕,重新使用已存在的ViewHolders。

如果您在第一次监听中设置了按钮,并且它重新使用ViewHolder进行第7次监听,则仍会选中该按钮(因为它已在ViewHolder中设置)。

要解决此问题,您需要每次在onBindViewHOlder中为您的listentries设置默认外观。

更新

public void onBindViewHolder(final ViewHolder viewHolder, final int position) {

    final Student student = stList.get(position);

    viewHolder.tvQuestionNumber.setText(student.getQuestionNumber());

    viewHolder.tvQuestion.setText(student.getQuestion());

    viewHolder.rbAns1.setText(student.getAnswer1());

    viewHolder.rbAns2.setText(student.getAnswer2());

    viewHolder.rbAns3.setText(student.getAnswer3());

    viewHolder.rbAns4.setText(student.getAnswer4());

    viewHolder.rbAns5.setText(student.getAnswer4());

    viewHolder.rgAnswers.clearCheck();

    viewHolder.rgAnswers.check(student.getSelectedRadioButtonId());

    viewHolder.rgAnswers.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            student.setSelectedRadioButtonId(checkedId);
            Log.v("hello"+position,checkedId+"");
        }
    });
}

我略微更新了你的新方法,也许这有帮助吗?

答案 5 :(得分:0)

在你的模型类中添加

private int checkedId = -1;

public int getCheckedId() {
    return checkedId;
}

public void setCheckedId(int checkedId) {
    this.checkedId = checkedId;
}

并在适配器中更改onBindViewHolder,如下所示:

 @Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
    viewHolder.tvQuestion.setText(stList.get(position).getQuestion());

    viewHolder.rbAns1.setText(stList.get(position).getAnswer1());
    viewHolder.rbAns2.setText(stList.get(position).getAnswer2());
    viewHolder.rbAns3.setText(stList.get(position).getAnswer3());
    viewHolder.rbAns4.setText(stList.get(position).getAnswer4());
    viewHolder.rbAns5.setText(stList.get(position).getAnswer5());

    viewHolder.radGrp.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(RadioGroup rgp, int checkedId) {
            // TODO Auto-generated method stub
            stList.get(position).setCheckedId(rgp.getCheckedRadioButtonId());
        }
    });

    viewHolder.radGrp.check(stList.get(position).getCheckedId());
}

答案 6 :(得分:0)

正如我看到你的代码......

只需添加单行

viewHolder.rgAnswers.setOnCheckedChangeListener(null);

在此行上方的onBindViewHolder()方法中

viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId()); ...

如果它解决了你的问题..我知道...... 我将向您解释其发生的原因.. 因为我遇到了 similer问题并使用此解决方案解决了。

答案 7 :(得分:0)

在学生班内添加一个布尔变量isSelected。现在,在每个radiogroup的checkedChangeListener上,更改isSelected的值以标记是否已选择某个值或未进行选择。现在在onBindViewHolder()里面做

    if(stList.get(position).isSelected){
  viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId());
    }else{
    viewHolder.rgAnswers.clearCheck();
    }

最后,您可以遍历整个列表并检查哪些对象isSelected为真

答案 8 :(得分:0)

RecyclerView来自ListView及其主要属性它在向上和向下滚动时重复使用单元格。 因此,即使列表中有大量数据,滚动时也不会轻弹。 由于在RecyclerView中重复使用单元格,您会遇到问题。

您可以通过使用getter和setter方法将RecyclerView列表数据绑定到Modal类来解决此问题。 您可以根据单元格位置和相应数据显示checkbox已选中或未选中。 在我的示例中,我使用setOnClickListener代替setOnCheckedChangeListenerto来显示已选中或未选中的复选框。

答案 9 :(得分:0)

大多数开发人员所做的主要有问题的代码段一次又一次地重新注册侦听器。

  • 所以第一个重点是不要在 onBindViewHolder 中注册监听器
  • 第二个重点是通过有效的方式设置标签来解决它,因此不要在标签中保存大对象,所以我们只会保存位置。

就我而言,我有四个单选按钮位于 list_item 布局中:

<块引用>
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val question = questions[position]
        holder.questionNumberTextView.text = "" + question.id + "."
        holder.questionTextView.text = question.question
        holder.myRadioGroup.tag = position
        if (question.selectedRadioButtonId != -1) {
            holder.myRadioGroup.check(question.selectedRadioButtonId);
        } else {
            //your always need to write else condition
            holder.myRadioGroup.clearCheck();
        }
}
 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    var itemLayoutView = LayoutInflater.from(parent.context)
        .inflate(R.layout.list_item, parent, false)

    val myViewHolder = MyViewHolder(itemLayoutView)
    myViewHolder.myRadioGroup.setOnCheckedChangeListener { radioGroup, radioButtonId ->
        val clickedPos = radioGroup.tag as Int
        Log.i("MyAdapter", "clicked pos:: $clickedPos  radioButtonId :: $radioButtonId")
        questions[clickedPos].selectedRadioButtonId = radioButtonId
    }
    return myViewHolder
}

enter image description here