Отображение постраничных списков

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

Подключите свой пользовательский интерфейс к модели представления

Вы можете подключить экземпляр LiveData<PagedList> к PagedListAdapter , как показано в следующем фрагменте кода:

Котлин

class ConcertActivity : AppCompatActivity() {
    private val adapter = ConcertAdapter()

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val viewModel: ConcertViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        viewModel.concerts.observe(this, Observer { adapter.submitList(it) })
    }
}

Ява

public class ConcertActivity extends AppCompatActivity {
    private ConcertAdapter adapter = new ConcertAdapter();
    private ConcertViewModel viewModel;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = new ViewModelProvider(this).get(ConcertViewModel.class);
        viewModel.concertList.observe(this, adapter::submitList);
    }
}

Поскольку источники данных предоставляют новые экземпляры PagedList , действие отправляет эти объекты в адаптер. Реализация PagedListAdapter определяет, как вычисляются обновления, и автоматически обрабатывает разбиение по страницам и спискам. Следовательно, вашему ViewHolder необходимо привязаться только к конкретному предоставленному элементу:

Котлин

class ConcertAdapter() :
        PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
    override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
        val concert: Concert? = getItem(position)

        // Note that "concert" is a placeholder if it's null.
        holder.bindTo(concert)
    }

    companion object {
        private val DIFF_CALLBACK = ... // See Implement the diffing callback section.
    }
}

Ява

public class ConcertAdapter
        extends PagedListAdapter<Concert, ConcertViewHolder> {
    protected ConcertAdapter() {
        super(DIFF_CALLBACK);
    }

    @Override
    public void onBindViewHolder(@NonNull ConcertViewHolder holder,
            int position) {
        Concert concert = getItem(position);

        // Note that "concert" can be null if it's a placeholder.
        holder.bindTo(concert);
    }

    private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK
            = ... // See Implement the diffing callback section.
}

PagedListAdapter обрабатывает события загрузки страницы с помощью объекта PagedList.Callback . Когда пользователь прокручивает страницу, PagedListAdapter вызывает PagedList.loadAround() , чтобы предоставить подсказки базовому PagedList о том, какие элементы он должен получить из DataSource .

Реализуйте дифференциальный обратный вызов

В следующем примере показана реализация areContentsTheSame() вручную, которая сравнивает соответствующие поля объекта:

Котлин

private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() {
    // The ID property identifies when items are the same.
    override fun areItemsTheSame(oldItem: Concert, newItem: Concert) =
            oldItem.id == newItem.id

    // If you use the "==" operator, make sure that the object implements
    // .equals(). Alternatively, write custom data comparison logic here.
    override fun areContentsTheSame(
            oldItem: Concert, newItem: Concert) = oldItem == newItem
}

Ява

private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK =
        new DiffUtil.ItemCallback<Concert>() {

    @Override
    public boolean areItemsTheSame(Concert oldItem, Concert newItem) {
        // The ID property identifies when items are the same.
        return oldItem.getId() == newItem.getId();
    }

    @Override
    public boolean areContentsTheSame(Concert oldItem, Concert newItem) {
        // Don't use the "==" operator here. Either implement and use .equals(),
        // or write custom data comparison logic here.
        return oldItem.equals(newItem);
    }
};

Поскольку ваш адаптер включает ваше определение сравнения элементов, адаптер автоматически обнаруживает изменения в этих элементах при загрузке нового объекта PagedList . В результате адаптер запускает эффективную анимацию элементов внутри вашего объекта RecyclerView .

Разница с использованием другого типа адаптера

Если вы решите не наследовать от PagedListAdapter — например, когда вы используете библиотеку, предоставляющую собственный адаптер, — вы все равно можете использовать функцию сравнения адаптера библиотеки подкачки, работая напрямую с объектом AsyncPagedListDiffer .

Добавьте заполнители в свой пользовательский интерфейс

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

Заполнители имеют следующие преимущества:

  • Поддержка полос прокрутки: PagedList предоставляет PagedListAdapter количество элементов списка. Эта информация позволяет адаптеру нарисовать полосу прокрутки, которая передает полный размер списка. При загрузке новых страниц полоса прокрутки не перемещается, потому что ваш список не меняет размер.
  • Индикатор загрузки не требуется: поскольку размер списка уже известен, нет необходимости предупреждать пользователей о том, что загружается больше элементов. Сами заполнители передают эту информацию.

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

  • Требуется подсчитываемый набор данных: экземпляры DataSource из библиотеки постоянства комнаты могут эффективно подсчитывать свои элементы. Однако если вы используете собственное локальное решение для хранения данных или сетевую архитектуру данных , определение количества элементов, составляющих ваш набор данных, может оказаться дорогостоящим или даже невозможным.
  • Требуется адаптер для учета выгруженных элементов: адаптер или механизм представления, который вы используете для подготовки списка к инфляции, должен обрабатывать нулевые элементы списка. Например, при привязке данных к ViewHolder вам необходимо указать значения по умолчанию для представления выгруженных данных.
  • Требуются представления элементов одинакового размера: если размеры элементов списка могут меняться в зависимости от их содержимого, например обновлений в социальных сетях, плавное затухание между элементами выглядит не очень хорошо. В этом случае мы настоятельно рекомендуем отключить заполнители.

Оставьте отзыв

Поделитесь с нами своими отзывами и идеями через эти ресурсы:

Трекер проблем
Сообщайте о проблемах, чтобы мы могли исправить ошибки.

Дополнительные ресурсы

Чтобы узнать больше о библиотеке подкачки, обратитесь к следующим ресурсам.

Образцы

Кодлабы

Видео

{% дословно %} {% дословно %} {% дословно %} {% дословно %}