【问题标题】:selection of radio button in Radio Group in Recycler view in android?在 android 的 Recycler 视图中选择 Radio Group 中的单选按钮?
【发布时间】:2016-05-03 10:36:36
【问题描述】:

我有带有单选组及其 4 个单选按钮的回收站视图。但是当我向下滚动列表时,项目的中间就像第一个一样。意味着如果我有 10 个项目,如果选择第一个项目按钮,那么 6 按钮也可以通过用户选择进行选择。

如何处理回收站视图中的问题。任何建议都将是可观的。 提前致谢。

enter code here 
 public class ViewHolder extends RecyclerView.ViewHolder {
    TextView quest, timestamp, answer;
    RadioGroup rg;
    RadioButton rb1, rb2, rb3, rb4;
    Button submit;
    public ViewHolder(View view) {
        super(view);
        quest = (TextView) itemView.findViewById(R.id.ques);
        timestamp = (TextView) itemView.findViewById(R.id.tym);
        answer = (TextView) itemView.findViewById(R.id.answer);
        rb1 = (RadioButton)itemView.findViewById(R.id.rb1);
        rb2 = (RadioButton)itemView.findViewById(R.id.rb2);
        rb3 = (RadioButton)itemView.findViewById(R.id.rb3);
        rb4 = (RadioButton)itemView.findViewById(R.id.rb4);
        rb4 = (RadioButton)itemView.findViewById(R.id.rb4);
        rg = (RadioGroup)itemView.findViewById(R.id.radio);
        submit = (Button)itemView.findViewById(R.id.submit);


        rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                int radioButtonID = group.getCheckedRadioButtonId();
                View radioButton = group.findViewById(radioButtonID);
                int clickedPos= (int) group.getTag();
                Log.v("currentpos",""+clickedPos);
                messageArrayList.get(clickedPos).setSelectedRadioButtonId(checkedId);
                int radioId = group.indexOfChild(radioButton);
                RadioButton btn = (RadioButton) group.getChildAt(radioId);
                final int currentPosition = getAdapterPosition();
                if (messageArrayList.get(clickedPos).getSelectedRadioButtonId() != -1 && checkedId != -1) {
                    try {

                        String selection = btn.getText().toString();
                        if (selection.equalsIgnoreCase(messageArrayList.get(clickedPos).getAnswer().toString())) {
                            Log.v("TAG", "USER OPTION" + "\t" + selection + "\n" + "CORRECT ANSWER IS" + "\t" + messageArrayList.get(clickedPos).getAnswer());
                           // rg.setVisibility(View.INVISIBLE);
                          //  answer.setVisibility(View.VISIBLE);
                           // answer.setText("Congrats, you are right. The answer is  " + messageArrayList.get(clickedPos).getAnswer().toString());


                     Toast.makeText(group.getContext(), "YOu are Right", Toast.LENGTH_SHORT).show();
                    } else {
                            // rg.setVisibility(View.INVISIBLE);
                            // answer.setVisibility(View.VISIBLE);
                            // answer.setText("Oops, you're wrong, the correct answer is  " + messageArrayList.get(clickedPos).getAnswer().toString());

                            Toast.makeText(group.getContext(), "You are Worng", Toast.LENGTH_SHORT).show();
                        }
                        Log.v("hello", selection);
                        String qusnn = quest.getText().toString();
                        Log.v("question", qusnn);
                        String read = "1";
                        try {
                            helper = new DBHelper(group.getContext());
                            database = helper.getWritableDatabase();
                            statement = database.compileStatement("update quiz set USERANS =? where QUESTION ='" + qusnn + "'");
                            statement.bindString(1, read);
                            statement.executeInsert();
                            database.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                            System.out.println("exception for send data in  table");
                        } finally {
                            database.close();
                        }

                    } catch (Exception e) {
                        StringWriter sw = new StringWriter();
                        e.printStackTrace(new PrintWriter(sw));
                        String exceptionAsString = sw.toString();
                        Log.v("hello", exceptionAsString);
                    }
                    Log.v("hello" + clickedPos, messageArrayList.get(clickedPos).getSelectedRadioButtonId() + "");


                }

            }});

    }
}


public ChatRoomThreadAdapter( ArrayList<Message> messageArrayList) {

    this.messageArrayList = messageArrayList;

    Calendar calendar = Calendar.getInstance();
    today = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView;
    if (viewType == SELF) {

        itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recycler_items, parent, false);
    }else{

        itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.secondlayout, parent, false);
    }


    return new ViewHolder(itemView);
}

@Override
public int getItemViewType(int position) {
    Message message = messageArrayList.get(position);
    if (message.getUsans().equals("0")) {
        return SELF;
    }

    return position;
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder,final int position) {
 final   Message message = messageArrayList.get(position);
    ((ViewHolder) holder).quest.setText(message.getMessage());
    ((ViewHolder) holder).rb1.setText(message.getOpt1());
    ((ViewHolder) holder).rb2.setText(message.getOpt2());
    ((ViewHolder) holder).rb3.setText(message.getOpt3());
    ((ViewHolder) holder).rb4.setText(message.getOpt4());
    ((ViewHolder) holder).answer.setText(message.getAnswer());
     String timestam= getTimeStamp(message.getCreatedAt());
    ((ViewHolder) holder).timestamp.setText(timestam);
   // ((ViewHolder) holder).rg.clearCheck();
  //  ((ViewHolder) holder).rg.setTag(position);
   // Log.e("select" + position, messageArrayList.get(position).getSelectedRadioButtonId() + "");

    ((ViewHolder) holder).rg.setTag(position);
    if (message.getSelectedRadioButtonId()!= -1){

        ((ViewHolder) holder).rg.check(message.getSelectedRadioButtonId());


    }else{
        //your always need to write else condition
        ((ViewHolder) holder).rg.clearCheck();
    }

}

@Override
public int getItemCount() {
    return messageArrayList.size();
}


public static String getTimeStamp(String dateStr) {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String timestamp = "";

    today = today.length() < 2 ? "0" + today : today;

    try {
        Date date = format.parse(dateStr);
        SimpleDateFormat todayFormat = new SimpleDateFormat("dd");
        String dateToday = todayFormat.format(date);
        format = dateToday.equals(today) ? new SimpleDateFormat("hh:mm a") : new SimpleDateFormat("dd LLL, hh:mm a");
        String date1 = format.format(date);
        timestamp = date1.toString();
    } catch (ParseException e) {
        e.printStackTrace();
    }

    return timestamp;
}

}

enter code here

      public class Message implements Serializable {
String id, message, opt1, opt2, opt3, opt4, answer, createdAt,usans;


public Message() {
}

public Message(String id, String message, String opt1, String opt2, String opt3, String opt4, String answer, String createdAt,String usans) {
    this.id = id;
    this.message = message;
    this.opt1 = opt1;
    this.opt2 = opt2;
    this.opt3 = opt3;
    this.opt4 = opt4;
    this.answer = answer;
    this.createdAt = createdAt;
    this.usans = usans;
}
private int checkedId = -1;

public int getSelectedRadioButtonId() {
    return checkedId;
}

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

public String getUsans() {
    return usans;
}

public void setUsans(String usans) {
    this.usans = usans;
}
public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public void setOpt1(String opt1) {
    this.opt1 = opt1;
}

public String getOpt1() {
    return opt1;
}

public void setOpt2(String opt2) {
    this.opt2 = opt2;
}

public String getOpt2() {
    return opt2;
}

public void setOpt3(String opt3) {
    this.opt3 = opt3;
}

public String getOpt3() {
    return opt3;
}

public void setOpt4(String opt4) {
    this.opt4 = opt4;
}

public String getOpt4() {
    return opt4;
}

public void setAnswer(String answer) {
    this.answer = answer;
}

public String getAnswer() {
    return answer;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public String getCreatedAt() {
    return createdAt;
}

public void setCreatedAt(String createdAt) {
    this.createdAt = createdAt;
}

}                                  

【问题讨论】:

  • 这可能是因为细胞被回收或重复使用。由于您已经进行了选择,因此 bindviewholder 方法不会重置无线电组并使用现有的。
  • 我该怎么做?
  • 好吧。如果您使用正确的 MVC 进行编码,那么您可以在 recycleview 单元模型中添加一个变量,该变量将保存选定的无线电索引。每当您更改索引时,请更新此变量以获取合适的模型。然后在绑定单元格时,您可以根据该变量设置选定的单选按钮
  • 这就是我在我的代码中所做的......一旦我更新了检查我的代码

标签: android radio-button radio-group android-recyclerview


【解决方案1】:

把这个写在你的适配器类的 onBindViewHolder() 中:

holder.setIsRecyclable(false);

我遇到了同样的问题,添加此代码对我有帮助。

编辑:问题是因为当我们在 Recycler View 中滚动时,单元格被回收,为了确保单元格不会被回收,使用了上述方法。

【讨论】:

  • 请为您的回答提供解释,这样做有助于 OP 以及遇到类似问题的其他人。
  • 修复了问题并在您选择单选按钮然后向下滚动然后向上删除您选择的内容时创建了另一个问题
  • 避免这种holder.setIsRecyclable(false);,因为您的视图永远不会被回收,这对您的应用程序的性能不利,This 是您可以处理它的方法
【解决方案2】:

看看你的代码和 cmets,我想你知道 RecyclerView 是如何工作的,尤其是重用视图。你唯一错过的是在所有场景中设置视图状态,我的意思是 - 你总是需要写 else部分代码

class MyViewHolder extends RecyclerView.ViewHolder {
            RadioGroup vRadioGroup;

            public MyViewHolder(View itemView) {
                super(itemView);
                vRadioGroup = (RadioGroup) itemView.findViewById(R.id.group1);
                //your other stuff
                vRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(RadioGroup radioGroup, int i) {
                        int clickedPos= (int) radioGroup.getTag();
                        messageArrayList.get(clickedPos).setSelectedRadioButtonId(radioButtonID);
                    }
                });
            }
 }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

                Message message = messageArrayList.get(position);

                //your other stuff
                holder.vRadioGroup.setTag(position);
                if (message.getSelectedRadioButtonId()!= -1){
                    holder.vRadioGroup.check(message.getSelectedRadioButtonId());
                }else{
                    //your always need to write else condition 
                    holder.vRadioGroup.clearCheck();
                }

        }

希望这会有所帮助..

【讨论】:

  • 在您定义视图的持有者类中设置setOnCheckedChangeListener。不在onBindViewHolder 方法内
  • 代码中的项目是什么,我如何获得它,我的问题是没有设置单选按钮。如果我有 12 个项目,如果我选择第一个并向下滚动该列表,则自动 6 个项目是用用户点击选择。(那个用户不能调试,只有我们可以看到)
  • sorry 其实item 我的代码对象曾经在我的最后测试...更新答案检查它
  • 你观察了我的代码一切......你明白我的问题吗?
  • yes... 复选框被选中的其他项目实际上你不是...它的hapening bcz 重用视图。解决方案是在没有选择组按钮时用holder.vRadioGroup.clearCheck(); 写其他部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 2016-06-17
  • 1970-01-01
  • 2017-01-20
  • 2019-11-15
  • 2017-11-23
  • 2013-02-02
相关资源
最近更新 更多