Один выбор в RecyclerView

Я знаю, что в классе recyclerview нет методов выбора по умолчанию, но я пробовал следующим образом,

public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.mTextView.setText(fonts.get(position).getName());
    holder.checkBox.setChecked(fonts.get(position).isSelected());

    holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked) {
                for (int i = 0; i < fonts.size(); i++) {
                    fonts.get(i).setSelected(false);
                }
                fonts.get(position).setSelected(isChecked);
            }
        }
    });
}

Пробуя этот код, я получил ожидаемый вывод, но совсем нет.

Я объясню вам с изображениями.

По умолчанию первый элемент выбран из моего адаптера

затем я пытаюсь выбрать 2-й и 3-й, а затем 4-й и, наконец, 5-й,

здесь должен быть выбран только пятый, но все пять выбираются.

Если я прокручиву список до дна и снова зайду,

Я получил то, что ожидал,

Как я могу преодолеть эту проблему? И иногда, если я прокручиваю список очень быстро, выбирается какой-то другой элемент. Как преодолеть эту проблему тоже?

Обновить

Пока я пытаюсь использовать notifyDataSetChanged() после fonts.get(position).setSelected(isChecked); Я получил следующее исключение,

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
        at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:1462)
        at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:2982)
        at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:7493)
        at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:4338)
        at com.app.myapp.screens.RecycleAdapter.onRowSelect(RecycleAdapter.java:111)

Любое решение будет высоко оценено.

Благодарю.

20 ответов

Решение

Решение проблемы:

public class yourRecyclerViewAdapter extends RecyclerView.Adapter<yourRecyclerViewAdapter.yourViewHolder> {

private static CheckBox lastChecked = null;
private static int lastCheckedPos = 0;

         ... ...

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

    holder.mTextView.setText(fonts.get(position).getName());
    holder.checkBox.setChecked(fonts.get(position).isSelected());
    holder.checkBox.setTag(new Integer(position));

    //for default check in first item
    if(position == 0 && fonts.get(0).isSelected() && holder.checkBox.isChecked())
    {
       lastChecked = holder.checkBox;
       lastCheckedPos = 0;
    }

    holder.checkBox.setOnClickListener(new View.OnClickListener() 
    {
        @Override
        public void onClick(View v) 
        {
           CheckBox cb = (CheckBox)v;
           int clickedPos = ((Integer)cb.getTag()).intValue(); 

           if(cb.isChecked)
           {
              if(lastChecked != null)
              {
                  lastChecked.setChecked(false);
                  fonts.get(lastCheckedPos).setSelected(false);
              }                       

              lastChecked = cb;
              lastCheckedPos = clickedPos;
          }
          else
             lastChecked = null;

          fonts.get(clickedPos).setSelected(cb.isChecked);
       }
   });
}
       ... ... 
}

Надеюсь, это поможет!

Уже слишком поздно отправлять, это может помочь кому-то еще. Используйте приведенный ниже код в качестве ссылки для проверки одного элемента в RecyclerView

/**
 * Created by subrahmanyam on 28-01-2016, 04:02 PM.
 */
public class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> {

    private final String[] list;
    private int lastCheckedPosition = -1;

    public SampleAdapter(String[] list) {
        this.list = list;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(parent.getContext(), R.layout.sample_layout, null);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.choiceName.setText(list[position]);
        holder.radioButton.setChecked(position == lastCheckedPosition);
    }

    @Override
    public int getItemCount() {
        return list.length;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        @Bind(R.id.choice_name)
        TextView choiceName;
        @Bind(R.id.choice_select)
        RadioButton radioButton;

        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
            radioButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    lastCheckedPosition = getAdapterPosition();
 //because of this blinking problem occurs so 
 //i have a suggestion to add notifyDataSetChanged();
                 //   notifyItemRangeChanged(0, list.length);//blink list problem
                      notifyDataSetChanged();

                }
            });
        }
    }
}

Вот как это выглядит

Единый выбор переработчика - лучший способ

Внутри вашего адаптера

private int selectedPosition = -1;

И на BindViewHolder

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {

    if (selectedPosition == position) {
        holder.itemView.setSelected(true); //using selector drawable
        holder.tvText.setTextColor(ContextCompat.getColor(holder.tvText.getContext(),R.color.white));
    } else {
        holder.itemView.setSelected(false);
        holder.tvText.setTextColor(ContextCompat.getColor(holder.tvText.getContext(),R.color.black));
    }

    holder.itemView.setOnClickListener(v -> {
        if (selectedPosition >= 0)
            notifyItemChanged(selectedPosition);
        selectedPosition = holder.getAdapterPosition();
        notifyItemChanged(selectedPosition);
    });
}

Это оно! Как видите, я просто уведомляю (обновляю) предыдущий выбранный элемент и новый выбранный элемент.

Мой Drawable установить его в качестве фона для дочерних просмотров переработчика

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="false" android:state_selected="true">
    <shape android:shape="rectangle">
        <solid android:color="@color/blue" />
    </shape>
</item>

Вам нужно очистить OnCheckedChangeListener перед установкой setChecked():

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

    holder.mRadioButton.setOnCheckedChangeListener(null);
    holder.mRadioButton.setChecked(position == mCheckedPosition);
    holder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            mCheckedPosition = position;
            notifyDataSetChanged();
        }
    });
}

Таким образом, это не вызовет java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling ошибка.

Просто используйте mCheckedPosition сохранить статус

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

            holder.checkBox.setChecked(position == mCheckedPostion);
            holder.checkBox.setOnClickListener(v -> {
                if (position == mCheckedPostion) {
                    holder.checkBox.setChecked(false);
                    mCheckedPostion = -1;
                } else {
                    mCheckedPostion = position;
                    notifyDataSetChanged();
                }
            });
        }

Похоже, здесь есть две вещи:

(1) Представления используются повторно, поэтому старый слушатель все еще присутствует.

(2) Вы изменяете данные, не уведомляя адаптер об изменении.

Я буду обращаться к каждому в отдельности.

(1) Просмотр повторного использования

В основном в onBindViewHolder вам дают уже инициализированный ViewHolder, который уже содержит представление. Тот ViewHolder может быть или не было ранее связано с некоторыми данными!

Обратите внимание на этот фрагмент кода прямо здесь:

holder.checkBox.setChecked(fonts.get(position).isSelected());

Если держатель был ранее связан, то у флажка уже есть прослушиватель, когда измененное состояние изменяется! Этот слушатель срабатывает в этот момент, что и стало причиной вашего IllegalStateException,

Простым решением будет удалить слушателя перед вызовом setChecked, Элегантное решение потребовало бы большего знания ваших взглядов - я призываю вас искать более хороший способ справиться с этим.

(2) Уведомить адаптер при изменении данных

Слушатель в вашем коде изменяет состояние данных, не уведомляя адаптер о любых последующих изменениях. Я не знаю, как работают ваши взгляды, так что это может или не может быть проблемой. Обычно, когда состояние ваших данных изменяется, вам нужно сообщить об этом адаптеру.

RecyclerView.Adapter имеет много вариантов на выбор, в том числе notifyItemChanged, что говорит о том, что конкретный элемент изменил состояние. Это может быть полезно для вашего использования

if(isChecked) {
    for (int i = 0; i < fonts.size(); i++) {
        if (i == position) continue;
        Font f = fonts.get(i);
        if (f.isSelected()) {
            f.setSelected(false);
            notifyItemChanged(i); // Tell the adapter this item is updated
        }
    }
    fonts.get(position).setSelected(isChecked);
    notifyItemChanged(position);
}

Это может помочь тем, кто хочет, чтобы работала одна кнопка -> Radio Button RecycleView - Gist

Если лямбда-выражения не поддерживаются, используйте вместо этого:

View.OnClickListener listener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        notifyItemChanged(mSelectedItem); // to update last selected item.
        mSelectedItem = getAdapterPosition();
    }
};

ура

Это происходит потому, что RecyclerView, как следует из названия, хорошо справляется с утилизацией своих ViewHolders. Это означает, что каждый ViewHolder, когда он выходит из поля зрения (на самом деле, это занимает немного больше, чем исчезновение из поля зрения, но имеет смысл упростить его таким образом), он перерабатывается; это означает, что RecyclerView берет этот ViewHolder, который уже надут, и заменяет его элементы элементами другого элемента в вашем наборе данных.

Теперь здесь происходит то, что после того, как вы прокрутите вниз и ваши первые выбранные ViewHolders исчезнут, они будут переработаны и использованы для других позиций вашего набора данных. Как только вы снова поднимитесь, ViewHolders, которые были связаны с первыми 5 элементами, теперь не обязательно будут одинаковыми.

Вот почему вы должны хранить в своем адаптере внутреннюю переменную, которая запоминает состояние выбора каждого элемента. Таким образом, в onBindViewHolder метод, вы можете узнать, был ли выбран элемент, ViewHolder которого в настоящее время привязан, или нет, и соответствующим образом изменить View, в этом случае состояние вашего RadioButton (хотя я бы предложил использовать CheckBox, если вы планируете выбирать несколько элементов).

Если вы хотите узнать больше о RecyclerView и его внутренней работе, я предлагаю вам проверить FancyAdapters, проект, который я начал на GitHub. Это набор адаптеров, которые реализуют выбор, перетаскивание элементов и пролистывание, чтобы отклонить возможности. Возможно, проверив код, вы сможете получить хорошее представление о том, как работает RecyclerView.

Этот простой работал для меня

private RadioButton lastCheckedRB = null;
...
@Override
public void onBindViewHolder(final CoachListViewHolder holder, final int position) {
  holder.priceRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        RadioButton checked_rb = (RadioButton) group.findViewById(checkedId);
        if (lastCheckedRB != null) {
            lastCheckedRB.setChecked(false);
        }
        //store the clicked radiobutton
        lastCheckedRB = checked_rb;
    }
});
            public class GetStudentAdapter extends 
            RecyclerView.Adapter<GetStudentAdapter.MyViewHolder> {

            private List<GetStudentModel> getStudentList;
            Context context;
            RecyclerView recyclerView;

            public class MyViewHolder extends RecyclerView.ViewHolder {
                TextView textStudentName;
                RadioButton rbSelect;

                public MyViewHolder(View view) {
                    super(view);
                    textStudentName = (TextView) view.findViewById(R.id.textStudentName);
                    rbSelect = (RadioButton) view.findViewById(R.id.rbSelect);
                }


            }

            public GetStudentAdapter(Context context, RecyclerView recyclerView, List<GetStudentModel> getStudentList) {
                this.getStudentList = getStudentList;
                this.recyclerView = recyclerView;
                this.context = context;
            }

            @Override
            public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View itemView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.select_student_list_item, parent, false);
                return new MyViewHolder(itemView);
            }

            @Override
            public void onBindViewHolder(final MyViewHolder holder, final int position) {
                holder.textStudentName.setText(getStudentList.get(position).getName());
                holder.rbSelect.setChecked(getStudentList.get(position).isSelected());
                holder.rbSelect.setTag(position); // This line is important.
                holder.rbSelect.setOnClickListener(onStateChangedListener(holder.rbSelect, position));

            }

            @Override
            public int getItemCount() {
                return getStudentList.size();
            }
            private View.OnClickListener onStateChangedListener(final RadioButton checkBox, final int position) {
                return new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (checkBox.isChecked()) {
                            for (int i = 0; i < getStudentList.size(); i++) {

                                getStudentList.get(i).setSelected(false);

                            }
                            getStudentList.get(position).setSelected(checkBox.isChecked());

                            notifyDataSetChanged();
                        } else {

                        }

                    }
                };
            }

        }
      public class LastTransactionAdapter extends RecyclerView.Adapter<LastTransactionAdapter.MyViewHolder> {

private Context context;
private List<PPCTransaction> ppcTransactionList;

private static int checkedPosition = -1;

public LastTransactionAdapter(Context context, List<PPCTransaction> ppcTransactionList) {
    this.context = context;
    this.ppcTransactionList = ppcTransactionList;
}

@NonNull
@Override
public LastTransactionAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.last_transaction_item, parent, false));
}

@Override
public void onBindViewHolder(@NonNull LastTransactionAdapter.MyViewHolder holder, int position) {
    holder.setLastTransaction(ppcTransactionList.get(position), position);
}

@Override
public int getItemCount() {
    return ppcTransactionList.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder {
    private LinearLayout linTransactionItem;
    private RadioButton radioButton;
    private TextView tvDate, tvMerchantName, tvAmount, tvStatus;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);

        linTransactionItem = itemView.findViewById(R.id.linTransactionItem);

        tvDate = itemView.findViewById(R.id.tvDate);
        tvMerchantName = itemView.findViewById(R.id.tvMerchantName);
        tvAmount = itemView.findViewById(R.id.tvAmount);
        tvStatus = itemView.findViewById(R.id.tvStatus);

        radioButton = itemView.findViewById(R.id.radioButton);
    }

    public void setLastTransaction(PPCTransaction ppcTransaction, int position) {
        tvDate.setText(ppcTransaction.getmDate());
        tvMerchantName.setText(ppcTransaction.getmMerchantName());
        tvAmount.setText(ppcTransaction.getmAmount());
        tvStatus.setText(ppcTransaction.getmStatus());

        if (checkedPosition == -1) {
            radioButton.setChecked(false);
        } else {
            if (checkedPosition == getAdapterPosition()) {
                radioButton.setChecked(true);
            } else {
                radioButton.setChecked(false);
            }
        }

        linTransactionItem.setOnClickListener(v -> {
            radioButton.setChecked(true);
            if (checkedPosition != getAdapterPosition()) {
                notifyItemChanged(checkedPosition);
                checkedPosition = getAdapterPosition();
            }
        });
    }
}

Возможно, я уже слишком поздно для этого ответа, но у меня есть решение, которое сохранит ваш выбор, когда вы откроете список переработчиков.

      var mSelectedItem = -1

// store saved selection
fun setSelection(position: Int) {
    mSelectedItem = position
}

override fun onBindViewHolder(holder: GroupHolder, position: Int) {
    holder.bind(dataList[position])
    holder.radioButton.isChecked = position == mSelectedItem
}

inner class GroupHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val radioButton: RadioButton = itemView.rbValue
    fun bind(data: Data) = with(itemView) {
        radioButton.text = data.name

        val clickListener = View.OnClickListener {
            mSelectedItem = bindingAdapterPosition
            notifyDataSetChanged()
            setSelection(mSelectedItem)             
        }
        radioButton.setOnClickListener(clickListener)
    }
}

Пожалуйста, попробуйте это... Это работает для меня..

В адаптере возьми разреженный логический массив.

SparseBooleanArray sparseBooleanArray;

В конструкторе инициализируйте это,

   sparseBooleanArray=new SparseBooleanArray();

В связыватель добавить,

@Override
public void onBindViewHolder(DispositionViewHolder holder, final int position) {
   holder.tv_disposition.setText(dispList.get(position).getName());
    if(sparseBooleanArray.get(position,false))
    {
        holder.rd_disp.setChecked(true);
    }
    else
    {
        holder.rd_disp.setChecked(false);


    }
    setClickListner(holder,position);
}

private void setClickListner(final DispositionViewHolder holder, final int position) {
    holder.rd_disp.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            sparseBooleanArray.clear();
            sparseBooleanArray.put(position, true);
            notifyDataSetChanged();


        }
    });
}

rd_disp - переключатель в файле XML.

Поэтому, когда представление рециркулятора загружает элементы, в bindView Holder он проверяет, содержит ли sparseBooleanArray значение "true", соответствующее его позиции.

Если возвращаемое значение равно true, тогда мы устанавливаем переключатель выбора true. Иначе мы устанавливаем false выбор. В onclickHolder я очистил sparseArray и установил значение true, соответствующее этой позиции. Когда я вызываю notify datasetChange, он снова вызывает onBindViewHolder, и условие проверяется снова. Это делает наш выбор, чтобы выбрать только определенное радио.

Итак, потратив так много дней на это, я пришел к тому, что сработало, и это хорошая практика,

  1. Создайте интерфейс, назовите его "listener": SomeSelectedListener.
  2. Добавьте метод, который принимает целое число:void onSelect(int position);
  3. Инициализируйте слушатель в конструкторе адаптера переработчика следующим образом: a) сначала объявите глобально как: private SomeSelectedListener listener b) затем в конструкторе инициализируйте как: this.listener = listener;
  4. Внутри onClick() флажка внутри onBindViewHolder(): обновите метод интерфейса / слушателя, передав позицию в виде: listener.onSelect (position)
  5. В модели добавьте переменную для отмены выбора, скажем, mSelectedConstant и инициализируйте ее там равной 0. Это представляет состояние по умолчанию, когда ничего не выбрано.
  6. Добавьте геттер и сеттер для mSelectedConstant в той же модели.
  7. Теперь перейдите к вашему фрагменту / деятельности и реализуйте интерфейс слушателя. Затем переопределите его метод: onSelect(int position). В этом методе итерируйте свой список, который вы передаете адаптеру, используя цикл for, и установите для SelectedConstant значение 0 для всех:

код

@Override
public void onTicketSelect(int position) {
for (ListType listName : list) {
    listName.setmSelectedConstant(0);
}

8. За пределами этого сделайте выбранную позицию постоянной 1:

код

list.get(position).setmSelectedConstant(1);
  1. Сообщите об этом изменении по телефону: adapter.notifyDataSetChanged(); сразу после этого.
  2. Последний шаг: вернитесь к своему адаптеру и обновите внутри onBindViewHolder (), после того как onClick() добавит код для обновления состояния флажка,

код

if (listVarInAdapter.get(position).getmSelectedConstant() == 1) {
    holder.checkIcon.setChecked(true);
    selectedTicketType = dataSetList.get(position);} 
else {
    commonHolder.checkCircularIcon.setChecked(false);
}

Я хочу поделиться тем, чего достиг, возможно, это кому-то поможет. код ниже из приложения, чтобы выбрать адрес из списка адресов, которые отображаются в cardview(cvAddress)так, чтобы по клику item(cardview) imageView внутри элемента должен быть установлен другой ресурс (выбрать / отменить выбор)

    @Override
public void onBindViewHolder(final AddressHolder holder, final int position)
{
    holderList.add(holder);
    holder.tvAddress.setText(addresses.get(position).getAddress());
    holder.cvAddress.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            selectCurrItem(position);
        }
    });
}

private void selectCurrItem(int position)
{
    int size = holderList.size();
    for(int i = 0; i<size; i++)
    {
        if(i==position)
            holderList.get(i).ivSelect.setImageResource(R.drawable.select);
        else
            holderList.get(i).ivSelect.setImageResource(R.drawable.unselect);
    }
}

Я не знаю, это лучшее решение или нет, но это сработало для меня.

Вот так выглядит класс Adapter:

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewHolder>{

Context context;
ArrayList<RouteDetailsFromFirestore> routeDetailsFromFirestoreArrayList_;
public int  lastSelectedPosition=-1;


public MyRecyclerViewAdapter(Context context, ArrayList<RouteDetailsFromFirestore> routeDetailsFromFirestoreArrayList)
{
    this.context = context;
    this.routeDetailsFromFirestoreArrayList_ = routeDetailsFromFirestoreArrayList;
}

@NonNull
@Override
public MyRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
{
    // LayoutInflater layoutInflater = LayoutInflater.from(mainActivity_.getBaseContext());
    LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
    View view = layoutInflater.inflate(R.layout.route_details, viewGroup, false);
    return new MyRecyclerViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull final MyRecyclerViewHolder myRecyclerViewHolder, final int i) {

    /* This is the part where the appropriate checking and unchecking of radio button happens appropriately */
    myRecyclerViewHolder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            if(b) {
                if (lastSelectedPosition != -1) {
     /* Getting the reference to the previously checked radio button and then unchecking it.lastSelectedPosition has the index of the previously selected radioButton */  
                    //RadioButton rb = (RadioButton) ((MainActivity) context).linearLayoutManager.getChildAt(lastSelectedPosition).findViewById(R.id.rbRadioButton);
                    RadioButton rb = (RadioButton) ((MainActivity) myRecyclerViewHolder.mRadioButton.getContext()).linearLayoutManager.getChildAt(lastSelectedPosition).findViewById(R.id.rbRadioButton);
                    rb.setChecked(false);
                }
                    lastSelectedPosition = i;
                    /* Checking the currently selected radio button */
                    myRecyclerViewHolder.mRadioButton.setChecked(true);
                }
        }
    });
}

@Override
public int getItemCount() {
    return routeDetailsFromFirestoreArrayList_.size();
}
} // End of Adapter Class

Внутри MainActivity.java мы называем ctor класса Adapter следующим образом. Переданный контекст имеет MainActivity для адаптера ctor:

myRecyclerViewAdapter = new MyRecyclerViewAdapter(MainActivity.this, routeDetailsList);

Следующее может быть полезно для RecyclerView с одним выбором.

Три шага для этого: 1) объявить глобальную целочисленную переменную,

private int mSelectedItem = -1;

2) в onBindViewHolder

 mRadio.setChecked(position == mSelectedItem);

3) в onClickListener

mSelectedItem = getAdapterPosition();
notifyItemRangeChanged(0, mSingleCheckList.size());
mAdapter.onItemHolderClick(SingleCheckViewHolder.this);

// Это работает для меня без каких-либо визуальных проблем

класс данных buttonData(кнопка val:RadioButton, позиция val: Int)

переменная selectedPosition = -1

      override fun onBindViewHolder(holder: SingleChoiceAdapter.OptionHolder, position: Int) {
    holder.viewDataBinding.option= options[position]
    holder.viewDataBinding.radioButton.setChecked(position == selectedPosition);
    buttonList.add( buttonData(holder.viewDataBinding.radioButton,position))

    holder.viewDataBinding.radioButton.setOnClickListener {
        selectedPosition=  position
        for(buttonData in buttonList ){
            buttonData.button.isChecked = buttonData.position == position
        }
    }
}

Я расскажу, как мне это удалось, и он отлично работает. Ни один из приведенных выше ответов не помог мне.

Итак, я сделал свой собственный переключатель. Пока не паникуйте. Это очень легко. Просто создайте пустой круг, который можно рисовать, а затем создайте круг с заливкой.

Теперь используйте 2 представления, одно с пустым рисунком, а другое с заполненным рисунком внутри него. Сделайте заполненный gone.

Теперь поиграйте вот так в адаптере.

BindViewHolder RecyclerView

Вы не слишком усложняете?

      SharedPreferences sharedPreferences =getSharedPreferences("appdetails",MODE_PRIVATE);

String selection=sharedPreferences.getString("selection", null);

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

String name=fonts.get(position).getName();

holder.mTextView.setText(name);

if(selection.equals(name)){   
holder.checkBox.setChecked(false);  // 
holder.checkBox.setChecked(true);
}
holder.checkbox.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
SharedPreferences sharedPreferences = getSharedPreferences("appdetails", MODE_PRIVATE);
                    SharedPreferences.Editor editor = sharedPreferences.edit();
                    editor.putString("selection", name);
                    r.setChecked(false);
                    editor.apply();
                    holder.checkBox.setChecked(true);
                }
      });
   }
Другие вопросы по тегам