RecyclerView и OnClick() как кликнуть по одному элементу?

Вообщем, есть проблема. Есть RecyclerView, со вложенным макетом CardView. При клике на кнопку, по понятным причинам нажимаются сразу несколько кнопок ( я так понял по position ). Как это обойти, сделать так, чтобы при нажатии - нажималась одна кнопка? В гугле копал, но не докопал, документацию читал, но уровень у меня не особо высокий, поэтому не могу определиться. Может кто помочь? Объяснить и наглядно показать как сделать ,чтобы было правильно, рассказать как ребенку почему и как? Огромный плюс от меня. Структура кода: ( Все к минимуму приведено, берегу ваши глаза :) )

 @Override
public CardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    Context context = parent.getContext();
    int layoutIdListItem = R.layout.fragment_card;
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(layoutIdListItem, parent, false);    // Подключение к card
    CardViewHolder cardViewHolder = new CardViewHolder(view);
    init();
    return cardViewHolder;
}

private void init() {
    //retrofit                  // это просто масиив инициализации, чтобы красиво все было

}


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


    if (partnerArrayList.size() == numberItems) {    // условие , если true , то изменяй CardView
        holder.bind(partnerArrayList.get(position));   // переход в изменение CardView
    }

}

@Override
public int getItemCount() {
    return numberItems;              // сколько элементов cardView?
}

class CardViewHolder extends RecyclerView.ViewHolder {

    private Button favorite;                // Вот допустим кнопочка, которую нужны клацать


    public CardViewHolder(@NonNull View itemView) {

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


    void bind(final Partner partner) {

        favorite.setOnClickListener(new View.OnClickListener() {   // и вот тут я кнопочку клацаю
            @Override                                      // но кнопочка клацается на всех CardView
            public void onClick(View v) {               // Укажите пожалуйста прям тут, что делать :)
                StateApp.setFavorite(partner.getId());
                favorite.setBackgroundResource(R.drawable.favorite_star_on_click);

Спасибо за ответы друзья, буду очень благодарен вам за помощь в такую трудную минуту для мня :(


Ответы (1 шт):

Автор решения: Sergei Buvaka

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

Второе. У вас действительно очень странно написан адаптер, и я бы рекомендовал вам его переписать с нуля, что-то вроде такого:

class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {

    private final ItemClickListener listener;
    private final List<YourData> items = new ArrayList<>();

    public YourAdapter(ItemClickListener listener) {
        this.listener = listener;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View root = LayoutInflater.from(parent.getContext()).inflate(viewType, null, false);
        return new ViewHolder(root);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.bind(items.get(position), listener);
    }

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

    public void update(List<YourData> items){
        this.items.clear();
        this.items.addAll(items);
        notifyDataSetChanged();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        private Button buttonOne;
        private Button buttonTwo;

        ViewHolder(View itemView) {
            super(itemView);
            buttonOne = itemView.findViewById(R.id.button_one);
            buttonTwo = itemView.findViewById(R.id.button_two);
        }

        void bind(YourData data, ItemClickListener listener){
            buttonOne.setOnClickListener(v -> listener.onClickButtonOne(data));
            buttonTwo.setOnClickListener(v -> listener.onClickButtonTwo(data));
        }
    }
}

Интерфейс OnItemClickListener. Его должна реализовать ваша View в которой находится ваш адаптер.

interface ItemClickListener {

    void onClickButtonOne(YourData data);

    void onClickButtonTwo(YourData data);
}

Любые обновления RecyclerView должны происходить с помощью метода update()

→ Ссылка