将选定的 RadioButton 文本保存在模型类中的 recyclerview 项中

从RecyclerViewitem 中,我试图将所选 RadioButton 的文本保存在模型类中。当我RadioButton从第一个项目中选择一个时,它的文本会被正确保存。问题是,与第 8 项相同位置的 RadioButton 文本也会自动保存。如果我从第 2 个项目中选择单选按钮,第 9 个项目中的文本也会自动保存,依此类推。如何解决这个问题呢?


onBindViewHolder 方法如下:


    @Override

    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {


    ...


    holder.radioGroup.setTag(position);

    holder.radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

        @Override

        public void onCheckedChanged(RadioGroup group, int checkedId) {


            int radioButtonID = group.getCheckedRadioButtonId();

            RadioButton radioButton = (RadioButton) group.findViewById(radioButtonID);

            int clickedPos = (Integer) group.getTag();

            models.get(clickedPos).setChecked(radioButtonID);


            if (radioButtonID > 0){

                models.get(clickedPos).setSelectedAns(radioButton.getText().toString());

            }


        }

    });

    holder.radioGroup.check(models.get(position).getChecked());

    Log.d("TAG", "At position " + position + " selected : " + models.get(position).getSelectedAns());


}


慕姐8265434
浏览 167回答 1
1回答

素胚勾勒不出你

问题是,尽管代码表面上看起来是正确的,但实际发生的是,当您调用 时holder.radioGroup.check(),它会触发您的onCheckedChanged()事件处理程序,就像用户启动它一样。由于视图被回收,位置 0 的视图被重用于列表中的位置 8。所以调用check()inonBindViewHolder()将调用onCheckedChanged(),从位置 0 选中的单选按钮仍然被选中(即checkedId,radioGroup. getCheckedRadioButtonId()当视图在位置 0 使用时,将返回选中的单选按钮的 ID)。真正的关键是这个models.get(clickedPos).setChecked(radioButtonID);考虑答案的第一段,您会意识到这将(错误地)更新位置 8 处的模型项,radioButtonID并使用在位置 0 处使用此视图时检查的 。解决此问题的一种方法是区分用户发起的更改和绑定发起的更改。例如,您可以通过向 中添加一个字段ViewHolder来指示视图当前是否正在绑定来执行此操作。class ViewHolder extends RecyclerView.ViewHolder{    TextView selectedAnswer;    RadioGroup radioGroup;    boolean isBinding;    ViewHolder(View itemView) {        super(itemView);        radioGroup = itemView.findViewById(R.id.radioGroup);        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(RadioGroup group, int checkedId) {                int position = getAdapterPosition();                RadioButton radioButton = (RadioButton) group.findViewById(checkedId);                /* Only update the model when onCheckedChange() was initiated by the user clicking                   a radio button, not when the adapter is binding the view. In that scenario, we                   are only interested in passing information FROM the model TO the view. */                if( !isBinding ) {                    models.get(position).setChecked(checkedId);                    models.get(position).setSelectedAns(radioButton != null ? radioButton.getText().toString() : "");                }                selectedAnswer.setText(  models.get(position).getSelectedAns() );            }        });        ...    }} @Overridepublic void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {    holder.isBinding = true;    ...    /* When calling check() here, we invoke onCheckedChanged(), which will       update the textview that displays the selected answer - so no need to call           holder.selectedAnswer.setText(  models.get(position).getSelectedAns() )       from here */    holder.radioGroup.check(models.get(position).getChecked());    holder.isBinding = false;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java