Jetpeck paging3实践(2)——结合smartrefreshLayout实现下拉刷新和加载更多

一、问题背景

上次实现了paging3无限加载网页数据,然后想实现一下之前原生实现的下拉刷新和底部上滑加载更多的效果,网上随便搜了下,没看到想要的demo效果, 自己撸一个,结合之前原生使用的smartRefreshLayout,可以很方便实现类似效果。

二、实现方案

(1)基于paging实现网页数据列表显示,可以正常无限下滑的效果。参考上篇文章( https://blog.51cto.com/baorant24/5766084 )。 (2)基于之前的demo,修改点如下: 1)添加对应依赖如下:

// 下拉刷新,上拉加载
    implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.3'
    // 没有使用特殊Header,可以不加这一依赖
    implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.3'

2)页面对应layout布局文件,使用SmartRefreshLayout组件替换之前使用的普通的recyclerview组件,修改如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

<!--    <androidx.recyclerview.widget.RecyclerView-->
<!--        android:id="@+id/recycler_view"-->
<!--        android:layout_width="match_parent"-->
<!--        android:layout_height="match_parent" />-->

    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:id="@+id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.scwang.smartrefresh.layout.header.ClassicsHeader
            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="match_parent" />
        <com.scwang.smartrefresh.layout.footer.ClassicsFooter
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </com.scwang.smartrefresh.layout.SmartRefreshLayout>

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

</FrameLayout>

3)对应activity的页面代码,对SmartRefreshLayout组件进行初始化以及初始化监听事件,如下所示:

import android.os.Bundle
import android.view.View
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.scwang.smartrefresh.layout.SmartRefreshLayout
import com.scwang.smartrefresh.layout.listener.OnRefreshListener
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

class Paging3Activity : AppCompatActivity() {

    private val viewModel by lazy { ViewModelProvider(this).get(MainViewModel::class.java) }

    private val repoAdapter = RepoAdapter()

    @OptIn(InternalCoroutinesApi::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_paging3)
        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        val progressBar = findViewById<ProgressBar>(R.id.progress_bar)
        // 初始化smartRefreshLayout组件
        val smartRefreshLayout = findViewById<SmartRefreshLayout>(R.id.refreshLayout)

        lifecycleScope.launch {
            viewModel.getPagingData().collect { pagingData -> repoAdapter.submitData(pagingData) }
        }
        repoAdapter.addLoadStateListener {
            when (it.refresh) {
                is LoadState.NotLoading -> {
                    // 根据LoadState,结束smartRefreshLayout的对应状态
                    smartRefreshLayout.finishRefresh()
                    smartRefreshLayout.finishLoadMore()
                    progressBar.visibility = View.INVISIBLE
                    recyclerView.visibility = View.VISIBLE
                }
                is LoadState.Loading -> {
                    progressBar.visibility = View.VISIBLE
                    recyclerView.visibility = View.INVISIBLE
                }
                is LoadState.Error -> {
                    val state = it.refresh as LoadState.Error
                    progressBar.visibility = View.INVISIBLE
                    Toast.makeText(this, "Load Error: ${state.error.message}", Toast.LENGTH_SHORT).show()
                }
            }
        }

        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = repoAdapter
//        val withLoadStateFooter = repoAdapter.withLoadStateFooter(MyLoadStateAdapter())
//        val withFooterAndHeader = repoAdapter.withLoadStateHeaderAndFooter(MyLoadStateAdapter(), MyLoadStateAdapter());
        //        recyclerView.adapter = withFooterAndHeader
        // 初始化smartRefreshLayout刷新事件,刷新页面数据
        smartRefreshLayout.setOnRefreshListener(OnRefreshListener {
            repoAdapter.refresh()
        })
    }
}

三、实现效果如下:

image.png image.png