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

标签 java android android-recyclerview android-radiobutton

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

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

}

最佳答案

问题是,虽然代码表面上看起来正确,但实际发生的是,当您调用 holder.radioGroup.check() 时,它会触发您的 onCheckedChanged() code> 事件处理程序就像用户启动它一样。

由于 View 被回收,位置 0 的 View 将被重新用于列表中的位置 8。因此,在 onBindViewHolder() 中对 check() 的调用将调用 onCheckedChanged(),并且位置 0 处选中的单选按钮仍处于选中状态(即checkedIdradioGroup.getCheckedRadioButtonId() 将返回在位置 0 使用 View 时选中的单选按钮的 ID。

真正的症结是这个

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

考虑答案的第一段,您会意识到这将(错误地)使用在位置 0 使用此 View 时检查的 radioButtonID 更新位置 8 处的模型项.

解决此问题的一种方法是区分用户启动的更改和绑定(bind)启动的更改。例如,您可以通过向 ViewHolder 添加一个字段来指示 View 当前是否正在绑定(bind)来执行此操作。

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

关于java - 从 recyclerview 项目中将选定的 RadioButton 的文本保存在模型类中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53013386/

相关文章:

Java,父类,方法抛出异常

java - 如何使用 RestFB 发布带有自定义缩略图的视频?

java - 如何在java中屏蔽字节来获取条件

java - 我试图解决 '15 puzzle' ,但我得到 'OutOfMemoryError'

java - Android 版本控制错误。 fragment 中的主题包装器错误

android - 安全回放 : Crash observed in MediaCodec

android - 屏幕关闭时前台服务在 Android 7.0+ 中不接收位置更新

android - 如何在 GridLayoutManager 中设置项目行的高度

java - 如何管理媒体播放器的多个实例?

android - RecyclerView 在向 List 添加新项目时移至顶部