当前位置: 移动技术网 > IT编程>开发语言>Java > Jetpack Paging3分页库

Jetpack Paging3分页库

2020年07月24日  | 移动技术网IT编程  | 我要评论

Jetpack Paging3分页库

简介
分页库可帮助您一次加载和显示一小块数据。按需载入部分数据会减少网络带宽和系统资源的使用量。
在这里插入图片描述

依赖
在这里插入图片描述

在app的build.gradle文件中添加依赖:

dependencies {
    ......

    def paging_version = "2.1.2"
    // kotlin使用 paging-runtime-ktx(Java使用 paging-runtime)
    implementation "androidx.paging:paging-runtime-ktx:$paging_version"
    // 或者-没有Android依赖项进行测试(Java使用 paging-common)
    testImplementation "androidx.paging:paging-common-ktx:$paging_version"
    // 可选-RxJava支持(Java使用 paging-rxjava2)
    implementation "androidx.paging:paging-rxjava2-ktx:$paging_version"
    //RecyclerView列表
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    //SwipeRefreshLayout刷新控件
    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
    //DataBinding数据绑定(没有用到可不添加)
    kapt "com.android.databinding:compiler:$gradle_version"
}

Paging的3个主要组件:

  • PagedList:可观察的分页列表,通常在ViewModel中创建PagedList对象,以及配置分页属性PagedList.Config
  • DataSource:数据源,可继承的数据源有三种

PageKeyedDataSource:按页加载,如请求数据时传入page页码
ItemKeyedDataSource:按条目加载,即请求数据需要传入其它item的信 息,如加载第n+1项的数据需传入第n项的id
PositionalDataSource:按位置加载,如加载指定从第n条到n+20条

  • Factory:数据工厂,需实现create()方法,返回一个DataSource对象

数据类:

data class User(
    val name: String,
    val age: Int,
    val index: Int = 0
) {
    override fun toString(): String {
        return "User(name='$name', age=$age, index=$index)"
    }
}

数据存储类

class UserViewModel : ViewModel() {
    private var users: LiveData<PagedList<User>>

    init {
        //初始化数据工厂
        val factory = UserDataSourceFactory()
        //初始化分页配置
        val config = PagedList.Config.Builder().apply {
            setPageSize(20)             //每页显示条目数量
            setInitialLoadSizeHint(20)  //首次加载条目数量 默认为 pageSize * 3
            setEnablePlaceholders(false)//当item为null是否使用PlaceHolder展示
            setPrefetchDistance(1)      //距离底部多少条数据开始预加载,设置0则表示滑到底部才加载
        }.build()
        users = LivePagedListBuilder<Int, User>(factory, config).build()
    }

    //获取数据
    fun getUsers(): LiveData<PagedList<User>> = users

}

DataSource 数据源(三选一)
PositionalDataSource数据源

//按位置加载,如加载指定从第n条到n+20条
class UserPosDataSource : PositionalDataSource<User>() {

    //初次加载
    override fun loadInitial(params: LoadInitialParams, callback: LoadInitialCallback<User>) {
        val result = setData(0, params.pageSize)
        callback.onResult(result, 0)
    }

    //分页加载
    override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<User>) {
        val result = setData(params.startPosition, params.loadSize)
        callback.onResult(result)
    }

    //模拟数据
    private fun setData(start: Int, size: Int): List<User> {
        val users = mutableListOf<User>()
        for (i in start until start + size) {
            users.add(User("张三$i", 20))
        }
        return users
    }

}

ItemKeyedDataSource数据源

//按条目加载,即请求数据需要传入其它item的信息,如加载第n+1项的数据需传入第n项的id
class UserItemDataSource : ItemKeyedDataSource<Int, User>() {
    //初次加载
    override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<User>) {
        val result = setData(0)
        callback.onResult(result, 0, 20)
    }

    //滑到底部加载数据
    override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<User>) {
        val result = setData(params.key)
        callback.onResult(result)
    }

    //滑倒顶部加载数据
    override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<User>) {
        val result = setData(params.key)
        callback.onResult(result)
    }

    //获取key
    override fun getKey(item: User): Int {
        return item.index
    }

    //模拟数据
    private fun setData(key: Int): List<User> {
        val users = mutableListOf<User>()
        for (i in key + 1..(key + 1) + 10) {
            users.add(User("张三$i", 20, i))
        }
        return users
    }

}

PageKeyedDataSource数据源

//按页加载,如请求数据时传入page页码
class UserPageDataSource : PageKeyedDataSource<Int, User>() {

    //初次加载
    override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, User>) {
        val result = setData(0)
        callback.onResult(result, 0, 1)
    }

    //加载下一页
    override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, User>) {
        val result = setData(params.key)
        callback.onResult(result, params.key + 1)
    }

    //加载上一页
    override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, User>) {
        val result = setData(params.key)
        callback.onResult(result, params.key - 1)
    }

    //模拟数据
    private fun setData(page: Int): List<User> {
        val users = mutableListOf<User>()
        for (i in page * 10 + 1..(page + 1) * 10) {
            users.add(User("张三$i", 20))
        }
        return users
    }
}

Factory 数据工厂

class UserDataSourceFactory : DataSource.Factory<Int, User>() {

    override fun create(): DataSource<Int, User> {
        return UserPosDataSource()
        //return UserPageDataSource()
        //return UserItemDataSource()
    }

}

Adapter 列表适配器

class UserAdapter() : PagedListAdapter<User, UserAdapter.ViewHolder>(DIFF_CALLBACK) {

    companion object {
        //对数据源返回的数据进行了比较处理, 
        //它的意义是——我需要知道怎么样的比较,
        //才意味着数据源的变化,并根据变化再进行的UI刷新操作
        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<User>() {
            override fun areItemsTheSame(oldItem: User, newItem: User): Boolean {
                return oldItem.name == newItem.name
            }

            override fun areContentsTheSame(oldItem: User, newItem: User): Boolean {
                return oldItem == newItem
            }

        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.context),
                R.layout.item_user_list,
                parent,
                false
            )
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        //绑定数据
        holder.dataBinding.setVariable(BR.user, getItem(position))
    }


    inner class ViewHolder(var dataBinding: ViewDataBinding) :
        RecyclerView.ViewHolder(dataBinding.root)
}

Activity

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: UserViewModel

    private var adapter: UserAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //初始化视图
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
        //绑定监听
        binding.myHandles = MyHandles()

        //初始化viewModel
        viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(UserViewModel::class.java)

        //初始化列表
        binding.rvView.layoutManager = LinearLayoutManager(this)
        adapter = UserAdapter()
        binding.rvView.adapter = adapter

        //通过viewModel拿到数据并提交数据
        viewModel.getUsers().observe(this, Observer {
            adapter!!.submitList(it)
        })

        //下拉刷新
        binding.srlLayout.setOnRefreshListener {
            srl_layout.isRefreshing = false
            viewModel.getUsers().value?.dataSource?.invalidate()
        }
    }

    inner class MyHandles{
        //主动点击刷新
        fun refresh(view: View) {
            adapter!!.submitList(null)
            viewModel.getUsers().value?.dataSource?.invalidate()
        }
    }
}

注意:如果使用的是PositionalDataSource数据源,主动刷新时需将数据列表置空,如:adapter!!.submitList(null),否则刷新数据,界面无法回到最顶部

显示:
在这里插入图片描述

本文地址:https://blog.csdn.net/summerrse/article/details/107542561

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网