DEV Community

Cover image for Utilizando o Jetpack Paging v3
João Gabriel
João Gabriel

Posted on

Utilizando o Jetpack Paging v3

O que é a Paging Library?

A Paging Library, é uma biblioteca criada pelo Google para resolver o problema da paginação de dados no Android.

Um problema que geralmente temos que resolver ao criar um aplicativo, é a solicitação de dados longos, que não exigem uma única vez, pois o usuário vê apenas uma pequena parte desses dados por vez.

Uma maneira de resolver esse problema, é adicionar um ScrollListener para o RecyclerView e carregar mais dados quando o usuário chega ao final da lista. Com esta abordagem, é difícil manter a eficiência, também a lógica da interface do usuário e gera uma lógica de dados complicada, o que dificulta a depuração e testes do projeto.

Vantagens

  • A Paging Library ajuda a carregar e exibir pequenos blocos de dados por vez.

  • O carregamento de dados parciais sob demanda reduz o uso da largura de banda da rede e dos recursos do sistema.

  • Facilmente integrada ao RecyclerView.

  • Mantém o controle das chaves a serem usadas para recuperar a página seguinte e a anterior.

  • Solicita automaticamente a página correta quando o usuário rola para o final da lista.

  • Garante que várias solicitações não sejam acionadas ao mesmo tempo.

  • Rastreia o estado de carregamento e permite exibi-lo em um RecyclerView item da lista, ou em qualquer outro local da interface do usuário e mostrar facilmente as cargas com falha.

Novidades Paging 3

  • Suporte interno para tratamento de erros, incluindo mecanismo de reload e retry.
  • Suporte à coroutines e Flow do Kotlin, assim como era ao LiveData e RxJava na versão 2.
  • Header, footer e separator incluídos na biblioteca.

Como implementar

Primeiramente, é necessário ter o Android Studio na versão 3.6 ou superior.

Adicionar a dependência no build.gradle

def paging_version = "3.0.0-alpha02"
implementation "androidx.paging: paging-runtime: $ paging_version"
Enter fullscreen mode Exit fullscreen mode

Até o momento da escrita deste artigo, esta é a versão atual da biblioteca

Fluxo dos dados

Alt Text

O principal componente na camada de Repository é o PagingSource.
Cada objeto PagingSource, define uma fonte de dados e recupera os dados dessa fonte, seja ela um banco de dados local ou uma API externa. No nosso exemplo utilizarei uma API externa:

class MyPagingSource(
    private val api: MyApi
) : PagingSource<Int, MyModel>() {
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MyModel> {
        return try {
            val result = api.getItems(params.key ?: STARTING_PAGE_INDEX)
            Page(
                data = result,
                prevKey = params.key,
                nextKey = result.nextPage ?: STARTING_PAGE_INDEX.plus(1)
            )
        } catch (e: IOException) {
            LoadResult.Error(e)
        } catch (e: HttpException) {
            LoadResult.Error(e)
        }
    }

    companion object {
        private const val STARTING_PAGE_INDEX = 1
    }
}
Enter fullscreen mode Exit fullscreen mode

A partir da criação do nosso PagingSource na camada de Repository, criaremos o nosso Pager.

O Pager é o responsável por configurar o tamanho de nossas páginas de requisição, através do PagingConfig, e auxiliar no fluxo dos dados.

fun getItems(): Flow<PagingData<MyModel>> {
    return Pager(
          config = PagingConfig(pageSize = 20),
          pagingSourceFactory = { MyPagingSource(api = api) }
    ).flow.cachedIn(viewModelScope)
}
Enter fullscreen mode Exit fullscreen mode

A partir da Paging v3, não é necessário converter Flow em LiveData.
Para manter um cache dos dados carregados no nosso ViewModel, chamamos o cachedIn passando o nosso androidx.lifecycle.viewModelScope

Agora teremos a nossa última etapa de implementação, que é passar os dados carregados para a nossa View.

Será necessário coletar os dados vindos do PagingData e passar para o nosso Adapter:

  • Solicitando os dados para o viewModel:
fun getData() {
    lifecycleScope.launch {
        viewModel.getItems().collectLatest {
            adapter.submitData(it)
        }
     }
}
Enter fullscreen mode Exit fullscreen mode
  • A implementação do adapter só precisa fazer uma extensão da classe PagingDataAdapter, e passar um DiffUtilCallback para diferenciar os itens recebidos:
class MyAdapter : PagingDataAdapter<MyModel, MyAdapter.MyViewHolder>(DiffUtilCallback()) {
   // a implementação do corpo do adapter permanece a mesma
}

class DiffUtilCallBack : DiffUtil.ItemCallback<MyModel>() {
    override fun areItemsTheSame(oldItem: MyModel, newItem: MyModel): Boolean {
        return oldItem.id == newItem.id
    }

    override fun areContentsTheSame(oldItem: MyModel, newItem: MyModel): Boolean {
        return oldItem == newItem
    }
}
Enter fullscreen mode Exit fullscreen mode

Esta foi a implementação necessária para fazer paginação no Android usando a Paging Library, obrigado pela leitura

Todo o conteúdo foi compartilhado no meu Github

Vou deixar aqui links adicionais com a documentação da biblioteca:

https://developer.android.com/topic/libraries/architecture/paging/v3-overview

https://codelabs.developers.google.com/codelabs/android-paging/#0

Top comments (0)