首页 > 其他分享 ># 安卓中实现分页加载方案(二)——paging基于ItemKeyedDataSource的加载方式

# 安卓中实现分页加载方案(二)——paging基于ItemKeyedDataSource的加载方式

时间:2022-09-30 17:04:02浏览次数:51  
标签:concert val ItemKeyedDataSource fun paging override 加载

安卓中实现分页加载方案(二)——paging基于ItemKeyedDataSource的加载方式

背景

组里在研究jetpeck库基于kotlin的使用,本次主要是研究paging的使用。

方案分析

paging的使用,基于ItemKeyedDataSource(PagedKeyUserDataSource )的加载方式目前已经是属于不被推荐的方案,不过还是写个总结记录下,会和后续推荐的方案进行对比。

实现方案

1、导入相关依赖

implementation "androidx.paging:paging-runtime-ktx:3.0.1"
testImplementation "androidx.paging:paging-common-ktx:3.0.1"
implementation "androidx.paging:paging-rxjava2-ktx:3.0.1"

2、创建实体类

class Concert {
     var name: String? = null
     var userId = 0
}

3、创建数据集

基于ItemKeyedDataSource的加载方式

class ConcertItemKeyedDataSource : ItemKeyedDataSource<Int, Concert>() {
    private val TAG = "ItemKeyedDataSource";

    var FIRST_PAGE = 1
    val PAGE_SIZE = 20

    /**
     * 获取下一页的起始位置
     */
    override fun getKey(item: Concert): Int {
        return item.userId
    }

    /**
     * 加载分页数据
     */
    override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Concert>) {
        Log.d(TAG, "正在请求第${FIRST_PAGE}数据")
        val concertList = mutableListOf<Concert>()
        val startPosition = FIRST_PAGE++ * PAGE_SIZE
        for (i in startPosition..(startPosition + 19)) {
            val concert = Concert()
            concert.name = "jack$i"
            concert.userId = i
            concertList.add(concert)
        }
        callback.onResult(concertList)
    }

    /**
     * 加载前执行方法
     * 只会执行一次
     */
    override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Concert>) {
        Log.d(TAG, "请求第${FIRST_PAGE}数据")
    }

    /**
     * 加载第一页数据
     */
    override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Concert>) {
        Log.d(TAG, "加载第一页数据")
        val concertList = mutableListOf<Concert>()
        for (i in 0..19) {
            val concert = Concert()
            concert.name = "jack$i"
            concert.userId = i
            concertList.add(concert)
        }
        callback.onResult(concertList)
    }
}

4、生成数据

class ConcertFactory : DataSource.Factory<Int, Concert>() {

    private var sourceLiveData: MutableLiveData<ConcertItemKeyedDataSource> = MutableLiveData()

    override fun create(): DataSource<Int, Concert> {
        val concertDataSource = ConcertItemKeyedDataSource()
        sourceLiveData.postValue(concertDataSource)
        return concertDataSource
    }
}

5、使用ViewModel来处理数据

class ConcertViewModel : ViewModel() {
    var convertList: LiveData<PagedList<Concert>>? = null
    private var concertDataSource: DataSource<Int, Concert>? = null

    init {
        val concertFactory = ConcertFactory()
        concertDataSource = concertFactory.create()
        val config = PagedList.Config.Builder()
                .setEnablePlaceholders(true).setPageSize(20).setPrefetchDistance(3).build()
        convertList = LivePagedListBuilder(concertFactory, config).build()
    }
}

6、使用adapter来显示数据

open class RecyclerViewAdapter: PagedListAdapter<Concert, RecyclerViewAdapter.RecyclerViewHolder>(DIFF_CALLBACK) {

    inner class RecyclerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val tv: TextView = view.findViewById(R.id.tv_content)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.adapter_paging, parent, false)
        return RecyclerViewHolder(view)
    }

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
        val concert = getItem(position)
        if (concert != null) {
            holder.tv.text = concert.name
        }
    }

    companion object {
        private val DIFF_CALLBACK: DiffUtil.ItemCallback<Concert> = object : DiffUtil.ItemCallback<Concert>() {
            override fun areItemsTheSame(oldConcert: Concert, newConcert: Concert): Boolean {
                return oldConcert.name == newConcert.name
            }

            override fun areContentsTheSame(oldConcert: Concert, newConcert: Concert): Boolean {
                return oldConcert.equals(newConcert)
            }
        }
    }
}

7、在activity中实现功能

class PagingActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_paging)

        val adapter = RecyclerViewAdapter()
        val viewModel: ConcertViewModel = ViewModelProvider(this).get(ConcertViewModel::class.java)

        concert_list.adapter = adapter
        concert_list.layoutManager = LinearLayoutManager(this)
        viewModel.convertList?.observe(this, Observer {
            adapter.submitList(it)
        })
    }
}

8、activity对应的xml布局文件如下

image.png

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.PagingActivity">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/concert_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

9、adapter中对应的item布局如下

image.png

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center_horizontal"
    android:layout_height="wrap_content">
<TextView
    android:layout_gravity="center_horizontal"
    android:id="@+id/tv_content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
</LinearLayout>

demo效果(可无限下滑)

image.png

标签:concert,val,ItemKeyedDataSource,fun,paging,override,加载
From: https://blog.51cto.com/baorant24/5727102

相关文章

  • SpringBoot 的 jar 包及应用配置文件加载
    SpringBoot打包如果你手动使用jar命令打过jar包(如下图)那么一定知道该jar包与使用spring-boot-maven-plugin插件打出来的jar包(如下图)不一样。SpringBoot运......
  • Visual Studio未能加载相应的Package包解决办法总结
    一、打开VisualStudio的时候,总提示未能加载相应的Package包,有时候还无法打开项目,各种提示通常解决方案:进入用户目录C:\Users\用户名\AppData\Local\Microsoft\VisualSt......
  • 前端性能优化 之 加载性能优化
    前端性能优化,分为两个部分:加载性能优化渲染性能优化本篇随笔介绍加载性能优化。加载性能优化本质:1、减少请求次数2、减少请求资源的大小3、网络优化1、减少......
  • 图片懒加载
    手动懒加载--利用指令的概念在src目录下,新建文件夹directives,再其中新建lazy.js:exportdefault{//这里的el就是使用了v-lazy指令的元素mounted(el){//保存图......
  • MyBatis加载Mapper映射文件的方式
    MyBatis加载Mapper的映射文件的方式我们都知道MyBatis是一款半自动的ORM框架,它的特点就是具有灵活的sql操作MyBatis是利用mapper的映射文件,来将数据库的中字段与Java的属性......
  • Vue面试题27:为什么要使用路由懒加载?(总结自B站up主‘前端杨村长’视频,仅供自用学习)
    这是一道应用题。当打包应用时,JavaScript包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应组件,这样就会更加......
  • 秋色园QBlog技术原理解析:Module之基类生命周期-页面加载(七)
    文章回顾:1:​​秋色园QBlog技术原理解析:开篇:整体认识(一)​​--介绍整体文件夹和文件的作用2:​​秋色园QBlog技术原理解析:认识整站处理流程(二)​​--介绍秋色园业务处理......
  • 在父组件中监听子组件页面是否加载完毕
    在父组件中监听子组件页面是否加载完毕//Parent.vue<Child@mounted="doSomething"/>//Child.vuemounted(){this.$emit("mounted");}//Parent.vue<C......
  • 图片懒加载
    vue语法实现图片懒加载一般网上说的懒加载都是说给图片src指定一张小的空白图片,真实url放在自定义的属性中,在图片进入视口后替换src在加载图片但在实际开发中,有时候会遇......
  • 反射之类的加载器
    反射之类的加载器@Testpublicvoidtest1(){//对于自定义类,使用系统类加载器进行加载ClassLoaderclassLoader=ClassLoaderTest.class.getClass......