实现原理原理非常简单
检测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>