Подтвердить что ты не робот

RecyclerView.onBindViewHolder вызывается только один раз

После многих часов исследований я наконец консультирую официальную помощь.

У меня есть RecyclerView.Adapter и RecyclerView.ViewHolders, которые отлично работали. Но по некоторым причинам я не понимаю, RecyclerView.Adapter.onBindViewHolder не называется должным образом.

    private class AttendeeAdapter extends RecyclerView.Adapter<AttendeeHolder> {
    /*FIELDS*/
    private List<Attendee> mAttendeeList;

    /*CONSTRUCTORS*/
    public AttendeeAdapter(List<Attendee> attendees) {
        mAttendeeList = attendees;
        //Log.i(TAG, "AttendeeAdapter size: " + getItemCount());
    }

На основании сообщения журнала (элемент подсчитывается как размер списка, как ожидалось), я предполагаю, что AttendeeAdapter был правильно создан.

Поэтому я ожидаю, что метод onBindViewHolder (VH, int) будет вызываться столько раз, сколько размер списка, но это не так. Этот метод называется только ONCE!

    /*METHODS*/
    @Override
    public AttendeeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
        View itemView = layoutInflater.inflate(R.layout.list_attendee, parent, false);
        return new AttendeeHolder(itemView);
    }

    @Override
    public void onBindViewHolder(AttendeeHolder holder, int position) {
        Attendee attendee = mAttendeeList.get(position);
        holder.bindAttendee(attendee, position);

        Log.i(TAG, "Binding ViewHolder #" + position);
        /* Binding ViewHolder #0 and that it */
    }

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

Мой AttendeeHolder (расширение RecyclerView.ViewHolder) выглядит следующим образом:

    private class AttendeeHolder extends RecyclerView.ViewHolder {
    /*FIELDS*/
    private EditText mAttendeeNameEditText;
    private Attendee mAttendee;

    /*CONSTRUCTOR*/
    public AttendeeHolder(View itemView) {
        super(itemView);
        mAttendeeNameEditText = (EditText) itemView.findViewById(R.id.edit_text_list_item);
        mAmountEditTextList = new ArrayList<>(eventMaxCount);
      }

    /*METHODS*/
    public void bindAttendee(Attendee attendee, final int position) {
        mAttendee = attendee;
        String attendeeName = mAttendee.getName();

        // Set the name to the EditText if a name has already been set
        if (attendeeName != null) {
            mAttendeeNameEditText.setText(attendeeName);
        }
    }
}

и реализован в основном коде как

List<Attendee> attendees = AttendeeLab.get().getAttendeeList();
     mAttendeeAdapter = new AttendeeAdapter(attendees);
     mAmountRecyclerView.setAdapter(mAttendeeAdapter);

Я думаю, что код будет работать (я думаю, что я не внес никаких изменений), но зависимости gradle могут быть неправильно установлены. Вот где я попытался изменить recyclerview-v7: 23.3.0 на recyclerview-v7: 23.1.0 или что-то еще (Ни один из них не работал).

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:support-v4:23.3.0'
compile 'com.android.support:recyclerview-v7:23.1.2'
}

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

4b9b3361

Ответ 1

Проблема не в вашем коде. Убедитесь, что вы установите layout_height на wrap_content дочернего элемента RecyclerView.

Ответ 2

Позаботьтесь о поведении onBindViewHolder в циклах RecyclerView. RecyclerView.ViewHolder position 0 itemView

android:layout_height="match_parent"

занимает текущий отображаемый экран. Scroll и onBindViewHolder должны быть запущены, но убедитесь, что getItemCount был установлен соответствующим образом.

Решение:

android:layout_height="wrap_content"

Решение с ConstraintLayout в виде раздутого itemView:

<?xml version="1.0" encoding="utf-8"?>    
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"><!-- IMPORTANT -->
    <!-- ... -->
</android.support.constraint.ConstraintLayout>

Ответ 3

Используйте те же версии для всех ваших библиотек поддержки:

dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])

testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:support-v4:23.3.0'
compile 'com.android.support:recyclerview-v7:23.3.0' //<<< here
}

Кроме того, RecyclerView должен быть добавлен с пакетом 'com.android.support:design:23.3.0' - переписывание класса, независимо от того, какая магия Gradle сделала в процессе сборки с этим "дублированным" пакетом, могла вызвать вашу проблему.

Ответ 4

Для людей, которые недавно столкнулись с этой проблемой и используют бета-версии SDK 28 библиотеки поддержки, измените целевой SDK на 27 и используйте версию 27.1.1 библиотеки поддержки (самые последние версии на момент написания).

Я боролся с этой проблемой в библиотеках 28.0.0-alpha3, изменил версию на 27.1.1 в моем app.gradle, и проблема была решена.

implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:support-vector-drawable:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'

Ответ 5

Также проверьте, не установлена ли высота самого вашего RecyclerView на android:layout_height="wrap_content" ИЛИ android:layout_height="match_parent". В обоих случаях он адаптирует высоту одного элемента и выглядит как один, но вы можете прокрутить список. Вместо этого установите высоту RecyclerView вручную.

Ответ 6

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