利用kotlin扩展函数实现RecyclerView无痕加载更多

本文介绍了一种简化RecyclerView加载更多和下拉刷新的方法。通过Kotlin扩展函数实现自动加载下一页数据的功能,有效减少了重复代码,提高了开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现原理原理非常简单

检测RecyclerView是否是滑动到最底部,如果是滑动到最底部就通知线程请求下一页数据

其实如果用Java写也就是实现RecyclerView的 setOnScrollListener事件,

判断滑动的RecyclerView最后一个item( findLastVisibleItemPosition )是否显示,如果显示的是最后一个数据就请求下一页。

但是为了减少相同代码,提高工作效率,可以把这个事件单独写个类。

例如Java可以这么写https://blog.youkuaiyun.com/u014537423/article/details/52556081

可以这么写https://www.jianshu.com/p/96f14f6a5bb4

 

原理是一样的,但是kotlin有个可以手动扩展自己的函数这个特性,写起来感觉代码简洁好多。

通知线程加载数据的接口

interface RecyclerListener {
    fun loadMore()
    fun refresh()
}

recyclerview的扩展函数

//在布局中,RecyclerView外嵌套一个swipeRefreshLayout,即可实现下拉刷新上拉加载更多
fun RecyclerView.setListener(l: RecyclerListener){
    setOnScrollListener(object : RecyclerView.OnScrollListener() {
        var lastVisibleItem: Int = 0
        val swipeRefreshLayout = this@setListener.parent
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)

            val layoutManager:RecyclerView.LayoutManager = recyclerView.layoutManager!!

            if (layoutManager is LinearLayoutManager) {
                lastVisibleItem = (recyclerView.layoutManager as LinearLayoutManager).findLastVisibleItemPosition()
            } else if (layoutManager is GridLayoutManager) {
                lastVisibleItem = (recyclerView.layoutManager as GridLayoutManager).findLastVisibleItemPosition()
            } else if(layoutManager is StaggeredGridLayoutManager) {
                val staggeredGridLayoutManager = recyclerView.layoutManager as StaggeredGridLayoutManager
                val lastPositions = IntArray(staggeredGridLayoutManager.spanCount)
                staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions)
                lastVisibleItem = findMax(lastPositions)
            }
        }

        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == recyclerView.adapter?.itemCount) {
                //下拉刷新的时候不可以加载更多
                if(swipeRefreshLayout is SwipeRefreshLayout){
                    if(!swipeRefreshLayout.isRefreshing){
                        l.loadMore()
                    }
                }else{
                    l.loadMore()
                }
            }
        }

    })

    val swipeRefreshLayout = this.parent
    if(swipeRefreshLayout is SwipeRefreshLayout){
        swipeRefreshLayout.setOnRefreshListener {
            l.refresh()
        }
    }
    
}
/**
 * 取数组中最大值
 *
 * @param lastPositions
 * @return
 */
fun  findMax(lastPositions:IntArray):Int {
    var max = lastPositions[0]
    for ( i in lastPositions.indices) {
        val value = lastPositions[i]
        if (value > max) {
            max = value
        }
    }

    return max;
}

使用

 recyclerview.setListener(object : RecyclerListener {
            override fun loadMore() {
                if (beans == null || beans!!.items == null) return
                if (beans!!.items!!.size >= beans!!.total) {
                    Toast.makeText(applicationContext, "没有更多数据了~", Toast.LENGTH_SHORT).show()
                } else {
                    pageNum++
                    getPhoto()
                }
            }

            override fun refresh() {
                pageNum = 0
                getPhoto()
            }
        })

xml,使用原生空间实现下拉刷新,上拉加载更多

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    >

    <include
        android:id="@+id/progress_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/view_progressbar"
        android:layout_centerInParent="true"
        android:visibility="gone"
        ></include>

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical"
            android:scrollbarSize="15px"
            android:fadeScrollbars="true"
            android:scrollbarThumbVertical="@color/grey_300"
            android:scrollbarStyle="insideOverlay"
            />

    </android.support.v4.widget.SwipeRefreshLayout>
    
</RelativeLayout>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值