什么是分页
在批处理中加载项目列表,而不是在单个GO中加载所有项目称为分页。打开Gmail Web应用程序时,默认情况下,您会在单个页面中看到50封电子邮件。要查看第51邮件,您必须单击下一页按钮。
为什么分页
在您的Gmail帐户中考虑大约一千多封电子邮件。立即加载所有一千封电子邮件将具有以下缺点:
- 数据库读取操作将非常昂贵。因此,您将获得具有大量延迟的列表。
- 获取列表后,在单个GO中渲染大量项目可以放慢速度。
使用分页的方法
在Android中,有两种实施分页的方法:
- 使用JetPack的
paging
库。您可以在我的其他博客Paging with MVVM and coroutines中使用MVVM查看分页库的详细实现。 - 使用我们自己的RecyClerview滚动侦听器的实现。
简单的滚动听众
本文侧重于我们自己的实施。有很多方法可以在Recyclerview的滚动侦听器中实现逻辑。我创建了滚动侦听器的通用实现,您可以简单地将其复制到代码中:
/**
* Created by Mohit Rajput on 20/03/22.
* Used for the load more functionality.
*/
abstract class PaginationScrollListener(private val layoutManager: LinearLayoutManager) :
RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val visibleItemCount: Int = layoutManager.childCount
val totalItemCount: Int = layoutManager.itemCount
val firstVisibleItemPosition: Int = layoutManager.findFirstVisibleItemPosition()
if (!isLoading() && !isLastPage()) {
if (visibleItemCount + firstVisibleItemPosition >= totalItemCount
&& firstVisibleItemPosition >= 0
) {
loadMoreItems()
}
}
}
protected abstract fun loadMoreItems()
abstract fun isLastPage(): Boolean
abstract fun isLoading(): Boolean
}
这是此滚动听众的示例用法:
private var isLoadingEmails = false
private val viewModel by viewModels<EmailsViewModel>()
private fun addScrollListener() {
recyclerView.addOnScrollListener(object :
PaginationScrollListener(recyclerView.layoutManager as LinearLayoutManager) {
override fun loadMoreItems() {
viewModel.fetchEmails()
}
override fun isLastPage() = viewModel.isAllEmailLoaded
override fun isLoading() = isLoadingEmails
})
}
解释
- 当您开始加载列表时,将
isLoadingEmails
值设置为true
。加载后,将其设置为false
。这可以通过通过实时数据或状态流触发的视图状态来管理。 -
viewModel.isAllEmailLoaded
值取决于API调用实现。如果您的API提供了列表项目的总数,则可以简单地将其实现为isAllEmailLoaded = currentList.size == totalListItems
。 - 此实现仅适用于
LinearLayoutManager
。我将很快为GridLayoutManager
提供有效的代码。
结论
更多或分页是几乎每个应用程序都使用的广泛概念。我们一次又一次地编写滚动侦听器的代码。因此,我创建了一个小型类别,该类可以更容易地构造负载,从而可以轻松地重复使用。如果加载正在进行,则不会同时进行加载调用。
感谢您的阅读。 ðð