Это руководство основано на обзоре библиотеки подкачки и описывает, как вы можете представлять списки информации пользователям в пользовательском интерфейсе вашего приложения, особенно когда эта информация меняется.
Подключите свой пользовательский интерфейс к модели представления
Вы можете подключить экземпляр 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
вам необходимо указать значения по умолчанию для представления выгруженных данных. - Требуются представления элементов одинакового размера: если размеры элементов списка могут меняться в зависимости от их содержимого, например обновлений в социальных сетях, плавное затухание между элементами выглядит не очень хорошо. В этом случае мы настоятельно рекомендуем отключить заполнители.
Оставьте отзыв
Поделитесь с нами своими отзывами и идеями через эти ресурсы:
- Трекер проблем
- Сообщайте о проблемах, чтобы мы могли исправить ошибки.
Дополнительные ресурсы
Чтобы узнать больше о библиотеке подкачки, обратитесь к следующим ресурсам.
Образцы
Кодлабы
Видео
- Android Jetpack: управляйте бесконечными списками с помощью RecyclerView и Paging (Google I/O '18)
- Android Jetpack: пейджинг
Рекомендуется для вас
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Обзор библиотеки страницы 2
- Перейти на страницу 3
- Сбор постраничных данных