Este guia se baseia na Visão geral da biblioteca Paging e descreve como você pode apresentar listas de informações aos usuários na IU do seu app, principalmente quando essas informações mudam.
Conectar a IU ao seu modelo de visualização
Você pode conectar uma instância de
LiveData<PagedList>
a um
PagedListAdapter
, conforme mostrado
no snippet de código a seguir:
Kotlin
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) }) } }
Java
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); } }
Como as fontes de dados fornecem novas instâncias de
PagedList
, a atividade envia
esses objetos para o adaptador. A implementação
PagedListAdapter
define como as atualizações são calculadas e processa automaticamente a
paginação e a diferenciação da lista. Portanto, seu
ViewHolder
só precisa ser vinculado a um item específico:
Kotlin
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. } }
Java
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. }
O PagedListAdapter
processa eventos de carregamento de página usando um objeto
PagedList.Callback
. À medida que o usuário rola, PagedListAdapter
chama
PagedList.loadAround()
para fornecer dicas ao PagedList
sobre
quais itens ele deve buscar em
DataSource
.
Implementar o callback de diferenciação
O exemplo a seguir mostra uma implementação manual de
areContentsTheSame()
,
que compara campos de objeto relevantes.
Kotlin
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 }
Java
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); } };
Como o adaptador inclui sua definição de comparação de itens, ele
detecta automaticamente mudanças nesses itens quando um novo objeto PagedList
é
carregado. Como resultado, o adaptador aciona animações de itens eficientes no seu
objeto RecyclerView
.
Diferenciação usando um tipo de adaptador diferente
Se você optar por não herdar de
PagedListAdapter
,
como nos casos em que é usada uma biblioteca que fornece o próprio adaptador, ainda será possível usar a
funcionalidade de diferenciação do adaptador da biblioteca Paging ao trabalhar diretamente com um objeto
AsyncPagedListDiffer
.
Fornecer marcadores na IU
Nos casos em que você quer que sua interface apresente uma lista antes que o app termine
de buscar dados, você pode mostrar marcadores de itens da lista aos usuários. O
PagedList
processa esse caso
apresentando os dados do item da lista como null
até que os dados sejam carregados.
Os marcadores têm os seguintes benefícios:
- Compatibilidade com barras de rolagem: o
PagedList
fornece o número de itens da lista para oPagedListAdapter
. Essas informações permitem que o adaptador desenhe uma barra de rolagem que transmita o tamanho total da lista. Quando novas páginas são carregadas, a barra de rolagem não pula porque o tamanho da lista não muda. - Nenhum ícone de carregamento é necessário: como o tamanho da lista já é conhecido, não é necessário avisar os usuários que mais itens estão sendo carregados. Os próprios marcadores transmitem essas informações.
No entanto, antes de acrescentar a compatibilidade com marcadores, lembre-se dos seguintes pré-requisitos:
- Necessidade de um conjunto de dados contáveis: as instâncias de
DataSource
da biblioteca de persistência Room podem contar os itens com eficiência. No entanto, caso você esteja usando uma solução de armazenamento local personalizada ou uma arquitetura de dados somente de rede, pode ser caro ou até impossível determinar quantos itens constituem seu conjunto de dados. - Necessidade de um adaptador para considerar os itens não carregados: o mecanismo de adaptador ou
apresentação usado para preparar a lista para inflação precisa
processar itens de lista nulos. Por exemplo, ao vincular dados a um
ViewHolder
, é necessário fornecer valores padrão para representar dados não carregados. - Necessidade de visualização de itens com o mesmo tamanho: se existir a possibilidade de os tamanhos de itens da lista mudarem com base no conteúdo, como em atualizações de redes sociais, o fading cruzado entre os itens não será bom. Nesse caso, recomendamos desativar os marcadores.
Enviar feedback
Envie comentários e ideias usando os recursos abaixo:
- Issue tracker
- Informe os problemas para que possamos corrigir os bugs.
Outros recursos
Para saber mais sobre a biblioteca Paging, consulte os recursos a seguir.
Exemplos
- Exemplo de paginação de Componentes da arquitetura do Android (link em inglês)
- Exemplo de paginação com rede (link em inglês)
Codelabs
Vídeos
- Android Jetpack: gerenciar listas infinitas com RecyclerView e Paging (Google I/O 2018)
- Android Jetpack: Paging
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado
- Visão geral da Biblioteca Paging 2
- Migrar para a Paging 3
- Coletar dados paginados