Android Jetpack- Paging3.0的使用

上一篇文章说了  Paging2.0的基本使用

https://blog.csdn.net/Leo_Liang_jie/article/details/109473099

其实 Paging3.0早出来,而且功能会更加强大,比如下面:

1:为 Kotlin 协程和流程提供一流更好的支持

2:分页数据缓存到内存中,保证应用在处理页面数据的时候,更有效的使用系统资源

等等

原理这个2.0文章已经说过了,这边直接上代码,

升级依赖到:3.0

implementation "androidx.paging:paging-runtime:3.0.0-alpha09"

读者可以把Android Studio 升级到最新版本,把鼠标放在依赖处,Gradle会提醒最新的版本是:

好了,直接上Adapter 代码,2.0继承的是 PagedListAdapter,3.0继承的是:PagingDataAdapter,除了这个之外,其他写法没区别

class MyPaged3ListAdapter extends PagingDataAdapter<MyDataBean, MyViewHolder> {

    public MyPaged3ListAdapter() {
        // 通过 构造方法 设置 DiffUtil.ItemCallback
        super(DIFF_CALLBACK);
    }

    private static DiffUtil.ItemCallback<MyDataBean> DIFF_CALLBACK =
            new DiffUtil.ItemCallback<MyDataBean>() {
                @Override
                public boolean areItemsTheSame(MyDataBean oldConcert, MyDataBean newConcert) {
                    // 比较两个Item数据是否一样的,可以简单用 Bean 的 hashCode来对比
                    return oldConcert.hashCode() == newConcert.hashCode();
                }

                @Override
                public boolean areContentsTheSame(MyDataBean oldConcert,
                                                  MyDataBean newConcert) {
                    // 写法基本上都这样写死即可
                    return oldConcert.equals(newConcert);
                }
            };


    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_my, parent, false);
        return new MyViewHolder(inflate);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        // getItem() 是 PagedListAdapter 内部方法,通过此方法可以获取到对应位置Item 的数据
        holder.bindData(getItem(position));
    }
}

再看DataSource,2.0用的 PositionalDataSource,3.0用的是 PagingSource

class MyPagingSource : PagingSource<Int, MyDataBean>() {

    /**
     *    params.key 是取 当前列表的起始节点
     *    params.loadSize 是获取当前列表的长度
     * */
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MyDataBean> {
        val startPosition = params.key ?: 0
        val loadSize = params.loadSize
        // 加载的数据
        val data = getData(startPosition, loadSize)
        return LoadResult.Page(
            data,
            // 往上加载的Key ,如果不可以往上加载就null
            null,
            // 加载下一页的key 如果传null就说明到底了
            startPosition + data.size
        )
    }
    
    /**
     *  模拟网络获取数据
     * */
    private fun getData(startPosition: Int, pageSize: Int): MutableList<MyDataBean> {
        val list = mutableListOf<MyDataBean>()
        for (i in startPosition until startPosition + pageSize) {
            list.add(MyDataBean(i))
        }
        return list
    }
}

创建Repository,2.0是创建 DataSource.Factory,3.0是创建自定义类,把 Pager 和PagingSource绑定设置

class MyRepository {

    /**
     *      pageSize = 20  设置每一页加载长度,
     *      和 PagingSource 的 params.loadSize对应
     * */
    fun getData() = Pager(PagingConfig(pageSize = 20)) {
        MyPagingSource()
    }

}

创建ViewModel,把Repository 和 LiveData 绑定

class MyPaging3ViewModel : ViewModel() {

    private val myRepository: MyRepository by lazy { MyRepository() }

    fun getData() = myRepository.getData().asLiveData()
}

看下Activity,和2.0没啥区别,就是 Adapter.submitData 需要在协程里面

class MainActivity : AppCompatActivity() {


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

        recyclerView.layoutManager = LinearLayoutManager(this)
        val myPagedListAdapter = MyPaged3ListAdapter()
        recyclerView.adapter = myPagedListAdapter
        /**
         *      ViewModel 绑定 Activity 生命周期
         * */
        val myViewModel = ViewModelProviders.of(this).get(MyPaging3ViewModel::class.java)

        /**
         *      ViewModel 感知数据变化,更新 Adapter 列表
         *      Adapter.submitData 这是一个用 suspend 修饰的方法,所以需要开启一个有生命周期的协程
         * */
        myViewModel.getData().observe(this, Observer {
            lifecycleScope.launch {
                myPagedListAdapter.submitData(it)
            }
        })


    }

}

运行效果和 2.0一样,测试没问题

上面代码亲测没问题,有问题请留言。

github连接:

https://github.com/LeoLiang23/PagingDemo.git

下面链接是我看过比较好的Paging的文章,也可以参考一下

https://mp.weixin.qq.com/s/qBxhtgjLluUZsHCinNHUAQ

猜你喜欢

转载自blog.csdn.net/Leo_Liang_jie/article/details/109647730