YmBok
搜索 充值水晶

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

以上


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

关于作者

还如一梦中 点击这里给我发消息

相关推荐

希望你会喜欢本站的内容

能用于cocos2d-x NDK的wstring和string的转换代码

std::string WString2String(const std::wstring&amp; wstr){ std::string curLocale = setlocale(LC_AL

2022-12-19 还如一梦中
《传奇世界》手游修改教程之怪物掉落设置

下面讲解如何修改传世世界手游中的物品掉落,再原始的版本中,掉落的设置无法满足玩家的喜欢,我们需要自己修改,有简单的方法,也有费时的方法,先教大家基础的方法,后面教大家快捷的方法。 首先再客户

2022-07-06 还如一梦中
《传奇世界》手游修改教程之道士BB召唤

道士控制自己技能召唤的宝宝,服务端/data/sbin/resource/script/system/skill 打开SkillScript.lua --新的道士宝宝召唤机制 SkillSc

2022-07-06 还如一梦中
《传奇世界》手游修改教程之攻沙时间修改

客户端和服务端ShaWarDB,关键的字段是时间逗号后面那个数字: --攻沙时间设置 改为3天后 local Items = { {holdTimes = 5,defensePos = '{x

2022-07-06 还如一梦中
《传奇世界》手游修改教程之Luac4加密

Lua是游戏的脚本一般不会直接打包到app里,要先加密为luac4,在传奇世界手游里android可以支持luac4,但苹果不行 我们通过lua编译工具(tools/luaecode)编译l

2022-07-06 还如一梦中
《一梦传世》元神版本纯源码手工编译教程

《一梦传世》 元神 版本纯源码手工编译 全部文件包含服务端与客户端(其中包含AndroidStudio工程,Eclipse工程,IOS工程)目录如下: 分别稍稍下目录内容: ymwe

2022-07-06 还如一梦中
白鹭冰雪源码编译服务端VIP教程

2022-07-02 还如一梦中
白鹭冰雪源码编译客户端VIP教程

2022-07-02 还如一梦中
刺客传奇引擎架设教程

荐服务端系统环境 Win Server 2008 64位 一、将服务端拷贝到服务器,解压YmcqServer.zip。 二、安装64位DBC2000: 安装DBC_2000,安装成功后打开安装目录,

2022-06-07 还如一梦中
刺客引擎编译打包修改免费视频教程(六)

6、delphi引擎服务端编译

2022-06-07 还如一梦中

友情链接