recyclerview.adapter 重置单选按钮

recyclerview.adapter resets radio-buttons

这是我的问题: https://youtu.be/k-N5uthYhYw

这是我的 onBindViewHolder() 方法。

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element

    holder.specName.setText(specList.get(position).getSpecName());

    // Assign a tag number to later identify what radio-button
    holder.specRadioBtn.setTag(new Integer(position));

    /* Event listenr for longClick - we prob. won't use it, but it's here just in case */
    holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {

            Toast.makeText(context, "Long press", Toast.LENGTH_SHORT).show();

            return false;
        }
    });

    /* Little hack to select its Radio Button when a specific row is tapped */
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // Turn rowSelectedFlag to true since the user selected this row
            rowSelectedFlag = true;

            // When the user taps on a row select that row's radio button
            holder.specRadioBtn.setChecked(true);

            // I'm not sure why, but locally the interface needs to be started by pointing it
            // to where it should drive the data (to send the params)
            tempInterface = new AdminUserSpecialty();

            // Call the interface to send the data (row spec-name and id) back to AdminUserSpecialty
            tempInterface.activateSpecSelect(specList.get(position).getSpecName().toString(),
                    specList.get(position).getSpecId().toString(), rowSelectedFlag);

            int clickedPos = ((Integer) holder.specRadioBtn.getTag());

            // Check if the radio button is already selected
            if (holder.specRadioBtn.isChecked()) {

                if (lastCheckedBtn != null) {

                    // Don't deselect if user taps on the same row several times
                    if (lastCheckedBtn == holder.specRadioBtn) {

                        // do nothing
                    }

                    // Otherwise do deselect the previously selected radio button
                    else {

                        lastCheckedBtn.setChecked(false);
                    }
                }

                lastCheckedBtn = holder.specRadioBtn;
                lastCheckedPos = clickedPos;
            }

            // If radio is not checked set the lastCheckedBtn to null (reset counter)
            else {
                lastCheckedBtn = null;
            }
        }
    });

    /* ----------------------------------------------------------------------*/


}

我似乎无法在 RecyclerView 滚动条上保留我的单选按钮选择。在滚动时,选择变得不稳定和随机。我知道 RecyclerView 的功能之一是在行离开屏幕时回收行,但我需要做什么才能保留我的选择?非常感谢。

保存单选按钮的选中/未选中状态(如果您想让用户select多个项目,您应该使用checkbox ) 在 onClick 事件发生时添加到您的模型(即列表中的项目应该有一个字段)。当您绑定 ViewHolder 时,请确保将复选框的值设置为您在模型中保存的值。

它的发生是因为 Recycling mechanism

(PS: ListViewRecyclerView 相同)。

解决这个问题:

  • 1) 添加一个 booelan 变量到你的模型来保存 RadioButton

  • 的状态
  • 2) 通过模型中的 booleanonBindViewHolder() 方法中更新您的 RadioButton 状态。

  • 3) 将 setOnCheckedChangeListener() 添加到您的 RadioButton 以监听他的状态 (checked/unchecked) 并在状态更改时更新模型中的布尔值。

我知道这个问题已经得到解答,但是如果你们中的一些人仍在寻找更简单的答案并且您的应用程序不太依赖 RecyclerView 视图回收功能(例如,如果您有固定大小的项目列表。 ..) 你总是可以设置你的回收视图缓存视图大小。这样它就不会回收您的视图因此它不会回收视图并且您将避免将选定的值复制到另一个视图...

yourRecyclerView..setItemViewCacheSize(yourItemList.size());