Fermer

mai 15, 2023

Pagination avec Paging3 | AU NOUVEAU Blog

Pagination avec Paging3 |  AU NOUVEAU Blog



Au cours du parcours de développement, nous pouvons avoir besoin d’afficher des données illimitées car le nombre d’utilisateurs d’une application mobile particulière augmente, tout comme les données associées à cette application.

Considérez l’application d’image, l’utilisateur fait défiler l’écran vers le bas et veut pouvoir récupérer plus de données du serveur pour l’afficher, mais que se passe-t-il si l’utilisateur fait défiler l’écran vers le haut en même temps ? En conséquence, nous devrons faire face à un grand nombre de cas et de gestion des erreurs.

Nous avons besoin d’une approche pour effectuer cette tâche qui charge efficacement toutes les données à partir de la base de données ou du réseau local, permet la mise en cache, réduit l’utilisation des ressources et économise également du temps de développement.

La pagination fait ce travail pour vous. La pagination est une bibliothèque Jetpack qui gère et charge efficacement les données à partir de différentes sources de données ; il est compatible avec Kotlin et fonctionne avec des solutions de threading, à savoir Flow, Coroutine, etc. Il est conçu pour suivre l’architecture de l’application Android. En outre, il prend en charge RxJava et LiveData.

Pagination3 & architecture applicative :

Paging3 utilise la couche de base de l’architecture de l’application Android comme référentiel-> Afficher le modèle -> composant Ui.

Source de pagination : La source de pagination est une classe abstraite générique qui prend deux types de clés de page Type et Type de réponse.

Téléavertisseur : Cette API consomme une source de pagination ou une source de données de médiateur distant et renvoie un flux de données paginées ; il peut s’agir de flux, d’observables ou de données en direct.

PagingDataAdapter : Il s’agit d’un composant d’interface utilisateur chargé de présenter les données paginées dans la vue de l’outil de recyclage ; il a quelques méthodes supplémentaires pour gérer l’en-tête et le pied de page lors de l’exécution.

Configuration de la pagination : Ici, vous pouvez définir la quantité de données qu’il charge pour chaque page.

Laissez-nous coder et réalisez-le

Ajoutez la dépendance requise au niveau de l’application :

mise en œuvre ‘androidx.paging:paging-runtime:3.1.1’


Référentiel d’images :

class ImageRepository(
private val apiService: ApiService = RemoteInjector.injectApiService(),
) {
companion object {
const val DEFAULT_PAGE_INDEX = 1
const val DEFAULT_PAGE_SIZE = 20
fun getInstance() = ImageRepository()
}

fun letImagesFlow(pagingConfig: PagingConfig = getDefaultPageConfig()): Flow<PagingData<ImageModel>> {
return Pager(
config = pagingConfig,
pagingSourceFactory = { ImagePagingSource(apiService) }
).flow
}

private fun getDefaultPageConfig(): PagingConfig {
return PagingConfig(pageSize = DEFAULT_PAGE_SIZE, enablePlaceholders = false)
}
}

Source de pagination de l’image :

class ImagePagingSource(var apiService: ApiService) : PagingSource<Int, ImageModel>() {

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ImageModel> {
val page = params.key ?: DEFAULT_PAGE_INDEX
return try {
val response = apiService.getImages(page, params.loadSize)

LoadResult.Page(
response, prevKey = if (page == DEFAULT_PAGE_INDEX) null else page - 1,
nextKey = if (response.isEmpty()) null else page + 1
)

} catch (exception: IOException) {
return LoadResult.Error(exception)
} catch (exception: HttpException) {
return LoadResult.Error(exception)
}
}

override fun getRefreshKey(state: PagingState<Int, ImageModel>): Int? {

}
}

Modèle d’affichage des images :

class ImagesViewModel(private val repository: ImageRepository = ImageRepository.getInstance()) :
ViewModel() {
fun fetchImages(): Flow<PagingData<String>> {
return repository.letImagesFlow()
.map { it -> it.map { it.url } }
.cachedIn(viewModelScope)
}
}

Images Adapter:
class ImagesAdapter :
PagingDataAdapter<String, UserViewHolder>(object : DiffUtil.ItemCallback<String>() {
override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
return oldItem == newItem
}

override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
return oldItem == newItem
}
}) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): UserViewHolder {
val inflater = LayoutInflater.from(parent.context)

return UserViewHolder(inflater.inflate(R.layout.item_image_view, parent,false))
}

override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)

}
}

class UserViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(url: String?) {
val image = itemView.findViewById<ImageView>(R.id.ivMain)
Glide.with(itemView.context).load(url).into(image)
}
}

Fragments d’images :

class ImagesFragment : Fragment() {

private lateinit var viewModel: ImagesViewModel
private var _binding: FragmentImagesBinding? = null
private lateinit var adapter: ImagesAdapter
private lateinit var loaderAdapter: LoaderStateAdapter

private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentImagesBinding.inflate(inflater, container, false)
return binding.root

}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
setupUi()
lifecycleScope.launch {
viewModel.fetchImages().distinctUntilChanged().collectLatest {
adapter.submitData(it)
}
}
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

private fun init() {
viewModel = defaultViewModelProviderFactory.create(ImagesViewModel::class.java)
adapter = ImagesAdapter()
loaderAdapter = LoaderStateAdapter()
}

private fun setupUi() {
val manager = GridLayoutManager(context, 2)

binding.rvImages.layoutManager = manager
binding.rvImages.adapter = adapter.withLoadStateFooter(loaderAdapter)

}
}

Si vous exécutez le code ci-dessus, il produira une sortie comme ci-dessous :

Si vous rencontrez des cas d’utilisation, n’hésitez pas à commenter et à applaudir si vous avez apprécié.

Retrouvez le code complet sur GithubGenericName.

Merci d’avoir lu et bon codage !

Références :
https://developer.android.com/topic/libraries/architecture/paging/v3-paged-data

TROUVÉ CELA UTILE ? PARTAGEZ-LE




Source link