简体   繁体   English

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

[英]Saving selected RadioButton's text in model class from recyclerview item

From RecyclerView item, I am trying to save the selected RadioButton's text in model class. RecyclerView项,我试图将所选RadioButton的文本保存在模型类中。 When I select a RadioButton from 1st item, it's text is saved appropriately. 当我从第一项中选择一个RadioButton ,它的文本将被适当地保存。 Problem is, RadioButton's text at the same position from 8th item is also auto saved. 问题是,第8项中相同位置的RadioButton的文本也会自动保存。 If I select radio button from 2nd item, text from 9th item is also auto saved, and so on. 如果我从第二项中选择单选按钮,则也会自动保存第九项中的文本,依此类推。 How to solve this problem? 如何解决这个问题呢?

onBindViewHolder method is given below : 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());

}

The problem is that although the code looks correct on the surface, what's actually happening is that when you call holder.radioGroup.check() , it triggers your onCheckedChanged() event handler just the same as if the user had initiated it. 问题在于,尽管代码看上去表面上是正确的,但实际上发生的是,当您调用holder.radioGroup.check() ,它会触发onCheckedChanged()事件处理程序,就像用户启动它一样。

Since the views are recycled, the view at position 0 is being reused for position 8 in the list. 由于视图是回收的,因此位置0的视图将重新用于列表中的位置8。 So the call to check() in onBindViewHolder() will call onCheckedChanged() , with the checked radio button from position 0 still checked (ie checkedId and radioGroup. getCheckedRadioButtonId() will return the ID of the radiobutton checked when the view was used at position 0). 因此,在onBindViewHolder()check()的调用将调用onCheckedChanged() ,位置0处的选中单选按钮仍处于选中状态(即, checkedIdradioGroup. getCheckedRadioButtonId()将返回在视图中使用该视图时选中的单选按钮的ID radioGroup. getCheckedRadioButtonId()位置0)。

The real crux is this 真正的症结在于

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

Consider the first paragraphs of the answer, and you'll realize that this will (incorrectly) update the model item at position 8 with the radioButtonID that was checked when this view was used at position 0. 考虑答案的第一段,您将意识到这将(错误地)使用在位置0使用此视图时检查的radioButtonID更新位置8的模型项。

One way to solve this is to distinguish between a user-initiated change and a binding-initiated change. 解决此问题的一种方法是区分用户发起的更改和绑定发起的更改。 You can for example do this by adding a field to the ViewHolder to indicate if the view is currently binding. 例如,您可以通过向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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从RECYCLERVIEW中的选定项目获取TEXT VIEW值 - How to get a TEXT VIEW value from selected item in RECYCLERVIEW RecyclerView更新项目的文本和图标OnClick - RecyclerView update item's text and icon OnClick 从RecyclerView Adapter类保存CheckBox状态 - Saving CheckBox state from RecyclerView Adapter class 获取选定的单选按钮文本作为字符串 - getting selected radiobutton text as string 在RadioGroup中选择RadioButton并从Backstack重新创建Fragment时,不会更新android RadioButton文本 - android RadioButton text is not updated when RadioButton is selected in RadioGroup, and Fragment is recreated from backstack 更改 RecyclerView 上仅选定项目的文本颜色 android Kotlin - Change text color of only selected item on RecyclerView android Kotlin 如何从 RecyclerView 项中复制文本? - How to copy text from the RecyclerView item? 在ListView中获取所选项目的标题文本 - Get selected item's header text in ListView 从 recyclerView 中选择 item 中的一个复选框并取消选择先前选择的复选框 - Select one checkBox in item from recyclerView and deselect previously selected checkBox 在recyclerview中选择项目后,如何从Firebase中删除值? - How to remove values from Firebase when item is selected in recyclerview?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM