RecyclerView не правильно обрабатывает OnClickListerner

188
30 июня 2017, 05:50
@Override
public void onBindChildViewHolder(@NonNull final MyChildViewHodler childViewHolder, final int parentPosition, final int childPosition, @NonNull final Course child) {
    childViewHolder.childProgress.setTextColor(context.getResources().getColor(R.color.lerning_child));
    childViewHolder.childProgress.setVisibility(View.VISIBLE);
    childViewHolder.imgCertification.setVisibility(View.GONE);
    Log.e("MyLerningFragmentAdapter=CREATE", parentPosition + "  " + childPosition + "");
    if (parentPosition!=0){
        childViewHolder.rippleLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("MyLerningFragmentAdapter=CLICK", parentPosition + "  " + childPosition + "");
            }
        });
    }

Судя по всему я не так добавляю Listener. Как быть тогда?

Куда его добавить нужно чтобы заработало. Такая же проблема у меня была с ListView. Вот еще видео прикладываю. Чтобы было понятнее

Видео с ошибкой

Answer 1

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

Т.к. у вас есть проверка

if (parentPosition != 0)

, при пролистывании наверх, когда на экране появляются элементы 0-го родителя, новый OnClickListener не устанавливается, а остаётся тем же самым, который был при создании ViewHolder'а, который используется для показа этого нового элемента.

UPDATE. Ответ на комментарий.

Можно например так:

@Override
public void onBindChildViewHolder(
        @NonNull final MyChildViewHodler childViewHolder,
        final int parentPosition,
        final int childPosition,
        @NonNull final Course child
) {
    int colorResId;
    switch (parentPosition) {
        case 4:
            colorResId = context.getResources().getColor(R.color.lerning_child_red);
            break;
        default:
            colorResId = context.getResources().getColor(R.color.lerning_child);
            break;
    }
    childViewHolder.childProgress.setTextColor(colorResId);
    ...
}

Но лучше конечно не завязываться именно на номер, а использовать дополнительное поле в классе Parent, которое для 4 имело бы одно значение, а для всех остальные другое. И тогда использовать что-то типа:

    Parent parent = getParent(parentPosition);
    int colorResId = context.getResources().getColor(parent.getColorFlag()
            ? R.color.lerning_child_red
            : R.color.lerning_child);
Answer 2

Видео посмотреть не могу. Попробуйте вот так

 childViewHolder.rippleLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (parentPosition == 0)
                    return;
                Log.e("MyLerningFragmentAdapter=CLICK", parentPosition + "  " + childPosition + "");
            }
        });
READ ALSO
Как вызвать event у jsf?

Как вызвать event у jsf?

Вопрос в следующем:

229
Многопоточность с использованием fork() и join()

Многопоточность с использованием fork() и join()

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

150
Behavior. Зависимость SearchView от BottomSheet

Behavior. Зависимость SearchView от BottomSheet

Нужно чтобы SearchView уходила наверх при движении BottomSheet

206
Не выводятся названия файлов с сервера в listview

Не выводятся названия файлов с сервера в listview

Всем доброго времени сутокЯ пишу приложение, в котором нужно подключиться к FTP серверу

153