为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕姐8265434 2021-12-10 12:35:28
从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());}
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

问题是,尽管代码表面上看起来是正确的,但实际发生的是,当您调用 时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() );

            }

        });


        ...

    }

}

 


@Override

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

}


查看完整回答
反对 回复 2021-12-10
  • 1 回答
  • 0 关注
  • 166 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号