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

在我的应用程序中,我在RecyclerView的帮助下显示了20个选择题。

如果我更改第一个RadioGroup的值并向下滚动,再次向上滚动移除RecycelarView的选定值,并且我还想进一步使用所选的RadioButton值,我也检查了link1但我不明白他在做什么。

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

  package com.testing.survey; import java.util.List; import android.annotation.SuppressLint; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TextView; @SuppressWarnings("rawtypes") public class DataAdapter extends RecyclerView.Adapter { private List stList; public DataAdapter(List students) { this.stList = students; } // Create new views @Override public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate( R.layout.list_row, null); // create ViewHolder ViewHolder viewHolder = new ViewHolder(itemLayoutView); return viewHolder; } @SuppressLint("UseValueOf") @Override 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).getAnswer4()); //viewHolder.rgAnswers.clearCheck(); viewHolder.rgAnswers.check(stList.get(position).getSelectedRadioButtonId()); viewHolder.rgAnswers.setTag(new Integer(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()).intValue(); //Student contact=(Student)group.getTag(); //contact.setSelectedRadioButtonId(radioButtonID); stList.get(clickedPos).setSelectedRadioButtonId(radioButtonID); Log.v("hello"+clickedPos,stList.get(clickedPos).getSelectedRadioButtonId()+""); } }); } // Return the size arraylist @Override public int getItemCount() { return stList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView tvQuestionNumber; public TextView tvQuestion; public RadioGroup rgAnswers; public RadioButton rbAns1,rbAns2,rbAns3,rbAns4,rbAns5; public Student singlestudent; public ViewHolder(View itemLayoutView) { super(itemLayoutView); tvQuestionNumber = (TextView) itemLayoutView.findViewById(R.id.tvQuestionNumber); tvQuestion = (TextView) itemLayoutView.findViewById(R.id.tvQuestion); rgAnswers=(RadioGroup)itemLayoutView.findViewById(R.id.rgAnswers); rbAns1=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer1); rbAns2=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer2); rbAns3=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer3); rbAns4=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer4); rbAns5=(RadioButton)itemLayoutView.findViewById(R.id.rbAnswer5); } } // method to access in activity after updating selection public List getStudentist() { return stList; } } 

出现此问题的原因是RecyclerView中的错误或Android SDK中的某个位置。 无论如何,我接受了另一个SO问题的建议 – onCheckedChanged自动调用 。

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

  1. RadioGroup上设置OnCheckedChangeListener

     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. 或者在RadioGroup内的所有RadioButton上设置onCheckedChangeListener

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

你可以这样做…..

在你的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 

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

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

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

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

      

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

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

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

        

适配器类如下:

  public class QuestionAdapter extends RecyclerView.Adapter { private List questionModels; public void setOnOptionSelected(OnOptionSelected onOptionSelected) { this.onOptionSelected = onOptionSelected; } private OnOptionSelected onOptionSelected; public List getQuestionModels() { return questionModels; } public void setQuestionModels(List 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 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(); 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的解决方案,但它没有正常工作(有时它保留旧的值)。 然后我改变了模型类中选择选项的方式。

样品

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

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

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

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

更新:

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

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

正如我看到你的代码……

只需添加单行

viewHolder.rgAnswers.setOnCheckedChangeListener(null);

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

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

如果它解决了你的问题..我知道… 我会向你解释为什么会发生这种情况.. 因为我遇到了 similer问题并解决了使用这个解决方案。

在你的模型类中添加

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

在学生class级内添加一个布尔variablesisSelected。 现在,在每个radiogroup的checkedChangeListener上,更改isSelected的值以标记是否已选择某个值或未进行任何选择。 现在在onBindViewHolder()里面就可以了

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

最后,您可以迭代整个列表并检查isSelected为true的对象

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

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