Android Jetpack Paging 3 下拉刷新和加载更多代码示例

使用Paging3实现列表的下拉刷新和加载更多


首先定义列表布局文件

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

定义PagingSource

class RecordPagingSource : PagingSource<Int,RecordItem>() {
private val lotteryRepository = LotteryRepository()
override fun getRefreshKey(state: PagingState<Int, RecordItem>): Int? {
return null
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, RecordItem> {
return try {
val page = params.key ?: 1
val pageSize = params.loadSize
var list = listOf<RecordItem>()
var result: ServiceResult<RecordItem> = repository.recordList(page,pageSize)
delay(1000)
//模拟数据
if(page < 5){
for(index in (page-1)*pageSize .. page * pageSize){
result.data.items.add(RecordItem("2021-11-11 11:11:11",1, "名字$index"))
}
}
if(result.errcode.toInt() == 0){
list = result.data.items
}
var prevKey: Int?
var nextKey: Int?
var initLoadSize = 16
if(page == 1){
prevKey = null
nextKey = initLoadSize/pageSize + 1
}else{
prevKey = page - 1
nextKey = if (result.data.items.size < pageSize) null else page + 1
}
return LoadResult.Page(
data = list,
prevKey = prevKey,
nextKey = nextKey
)
} catch (e: Exception) {
e.printStackTrace()
LoadResult.Error(e)
}
}
}

定义ViewModel

class RecordViewModel : ViewModel() {
fun loadRecordList() : Flow<PagingData<RecordItem>> {
return Pager(
config = PagingConfig(
pageSize = 8,
prefetchDistance = 1,
initialLoadSize = 16
),
pagingSourceFactory = {
RecordPagingSource()
}
).flow
}
}

定义ViewModelFactory

class RecordViewModelFactory : ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return RecordViewModel() as T
}
}

定义PagingDataAdapter

class RecordPagingDataAdapter(
val activity: RecordActivity
) :PagingDataAdapter<RecordItem, RecordPagingDataAdapter.ViewHolder>(
object:DiffUtil.ItemCallback<RecordItem>(){
override fun areItemsTheSame(oldItem: RecordItem,newItem: RecordItem): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: RecordItem,newItem: RecordItem): Boolean {
return oldItem == newItem
}
}
)
{
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = getItem(position)
item?.let {
holder.nameText.text = item.name
with(holder.itemView) {
tag = item
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemListBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
inner class ViewHolder(binding: ItemListBinding) : RecyclerView.ViewHolder(binding.root) {
val nameText: TextView = binding.nameText
}
}

在Activity中

//view model
recordViewModel = ViewModelProvider(this, RecordViewModelFactory()).get(RecordViewModel::class.java)
// Adapter
//var recyclerViewAdapter = RecordRecyclerViewAdapter(activity as RecordActivity,coinDataList)
//lotteryRecordRecyclerView.adapter = recyclerViewAdapter
var recyclerViewAdapter = RecordPagingDataAdapter(activity as RecordActivity)
binding.apply {
recyclerView.adapter = recyclerViewAdapter.withLoadStateFooter(
LoadMoreAdapter(activity as RecordActivity)
)
recyclerView.layoutManager = LinearLayoutManager(activity)
var loading = false
// 刷新
binding.swipeRefreshLayout.setOnRefreshListener {
recyclerViewAdapter.refresh()
/*lifecycleScope.launch{
recyclerViewAdapter.loadStateFlow.collectLatest { state->
logI(TAG,"setOnRefreshListener:" + state.refresh.toString())
if (state.refresh !is LoadState.Loading) recyclerViewAdapter.refresh()
}
}*/
}
recyclerViewAdapter.addLoadStateListener {
logI(TAG,"addLoadStateListener:" + it.refresh.toString())
when (it.refresh) {
is LoadState.NotLoading -> {
loading = false
binding.swipeRefreshLayout.isRefreshing = false
}
is LoadState.Loading -> {
loading = true
}
is LoadState.Error -> {
loading = false
binding.swipeRefreshLayout.isRefreshing = false
}
}
}
}
// 加载数据
lifecycleScope.launchWhenCreated {
recordViewModel.loadRecordList().collectLatest {
recyclerViewAdapter.submitData(it)
}
}

以上


本站内容来源于作者发布和网络转载,如有版权相关问题请及时与我们取得联系,我们将立即删除。

 关于作者
 热门教程
通过Git下载和提交代码的命令记录
安装好git后: 1、配置邮箱 git config --global user.name ymbok git con
2023-08-15
剑道仙尊
64
通过ADB在Android系统中快捷截屏和录屏的方法
连上ADB线后: 截图 创建一个BAT文件,用于截图,直接双击运行即可将图片保存到D:\screenshot目录,提前
2023-08-15
剑道仙尊
118
Android12 源码下载与编译
下载Android12 源码 sudo apt-get update 安装curl sudo apt install
2023-04-25
剑道仙尊
128
android生成签名文件jks并获取SHA1
打开Android Studio终端,输入: keytool -genkey -alias app -keyalg R
2022-07-13
剑道仙尊
96
Flutter开发APP更改状态栏文字颜色
void main(){ runApp(MyApp()); /// 状态栏文字黑色 SystemChrome
2022-06-09
剑道仙尊
136
Android Swicth按钮样式自定义
&lt;Switch android:id="@+id/switch_btn" android:layout_wi
2022-06-07
剑道仙尊
141
Pagging3写起来太麻烦,简单封装及其简单
Pagging3分页写起来很麻烦,这里分享一下我的简化开发的方法,思路就是把获取数据的函数分离出来 首先定义一个基础的
2022-06-07
剑道仙尊
212
在项目中使用Hilt Retrofit使用总结
直接开始,首先我们看看怎么使用Hilt编写 Retrofit 接口请求类 用@Provides注解定义可注入的实例的提
2022-06-07
剑道仙尊
205
Android Jetpack Paging 3 下拉刷新和加载更多代码示例
使用Paging3实现列表的下拉刷新和加载更多 首先定义列表布局文件 &lt;androidx.swiperefres
2022-06-07
剑道仙尊
441
StatefulBuilder实现Dialog的刷新
在Flutter中使用Dialog时,因为 showDialog返回的context与当前页面的 context不是同
2022-06-07
剑道仙尊
139