Utilizando a nova versão do Jetpack Paging

Compartilhe

Compartilhar no facebook
Compartilhar no google
Compartilhar no twitter
Compartilhar no linkedin

O que é a paging library?

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 um usuário chegar ao final do RecylerView. Nessa abordagem, era difícil manter a eficiência e a lógica da interface do usuário. Além disso, gera uma lógica de dados complicada, o que dificulta a depuração e o teste do projeto.

A paging library é uma biblioteca criada para resolver o problema da paginação de dados no Android. 

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 tentar 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. Até o momento da escrita deste artigo, esta é a versão atual da biblioteca

def paging_version = "3.0.0-alpha07"
implementation "androidx.paging: paging-runtime:$paging_version"

view raw
build.gradle
hosted with ❤ by GitHub

Fluxo dos dados

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

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
}
}

view raw
MyPagingSource.kt
hosted with ❤ by GitHub

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 request através do PagingConfig e nos auxiliar no fluxo de dados.

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

view raw
Pager.kt
hosted with ❤ by GitHub

A partir do 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 iremos 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)
}
}
}

view raw
Fragment.kt
hosted with ❤ by GitHub

  • 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
}
}

view raw
MyAdapter.kt
hosted with ❤ by GitHub

Todo o conteúdo foi compartilhado com um projeto exemplo está nesse link!

 

Links adicionais :

Deixe um comentário

Categorias

Posts relacionados

Siga-nos

Baixe nosso e-book!

%d blogueiros gostam disto: