Android RecyclerView page/paging load,based on AsyncListUtil,kotlin(4)
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
class MainActivity : AppCompatActivity() {
companion object {
val TAG = "fly"
}
val mAdapter = MyAdapter()
var mRecyclerView: RecyclerView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mRecyclerView = findViewById<RecyclerView>(R.id.recycler_view)
mRecyclerView?.layoutManager = GridLayoutManager(this, 4).apply {
orientation = GridLayoutManager.VERTICAL
}
mRecyclerView?.adapter = mAdapter
//假设已经知道全量数据,后续的分段是把源数据一片一片的截出来,装到新的分页数据集里面
val ITEMS = ArrayList<MyData>()
for (i in 0..3000) {
var data = MyData("@$i")
ITEMS.add(data)
}
//新的分页数据集
var pageItems: ArrayList<MyData>? = ArrayList()
for (i in 0 until ITEMS.size) {
pageItems?.add(MyData("-1"))
}
mAdapter.onChange(pageItems!!)
PagingRecyclerViewUtil.PAGE_SIZE = 500
var util =
PagingRecyclerViewUtil(mRecyclerView!!, object : PagingRecyclerViewUtil.PagingListener {
override fun onFillData(data: Array<out Any>, startPosition: Int, itemCount: Int) {
Log.d(TAG, "onFillData $startPosition $itemCount")
paging(ITEMS, pageItems!!, startPosition, itemCount)
}
})
mRecyclerView?.addOnScrollListener(object : OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
util.onRangeChanged()
}
})
//RecyclerView启动后默认滚到最底部
mRecyclerView?.scrollToPosition(mAdapter.getItemCount() - 1)
}
fun paging(
sourceItems: ArrayList<MyData>,
pageItems: ArrayList<MyData>,
startPosition: Int,
itemCount: Int
) {
var cnt = itemCount
if ((startPosition + itemCount) > sourceItems.size) {
cnt = sourceItems.size - startPosition
}
for (i in 0 until cnt) {
var idx = startPosition + i
pageItems?.set(idx, sourceItems.get(idx))
}
runOnUiThread {
mAdapter.onChange(pageItems!!)
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class MyAdapter() : RecyclerView.Adapter<MyViewHolder>() {
var items: ArrayList<MyData>? = ArrayList()
fun onChange(items: ArrayList<MyData>) {
this.items = items
this.notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(android.R.layout.simple_list_item_2, parent, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return items?.size!!
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.name.text = "$position"
holder.desc.text = items?.get(position)?.desc
}
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val name: TextView = itemView.findViewById(android.R.id.text1)
val desc: TextView = itemView.findViewById(android.R.id.text2)
}
data class MyData(var desc: String)
import android.util.Log
import androidx.recyclerview.widget.AsyncListUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
class PagingRecyclerViewUtil(rv: RecyclerView, pagingListener: PagingListener) {
companion object {
//每一页的数据数量
//如果需要重新修改page_size值,需要在使用PagingRecyclerViewUtil之前
//PagingRecyclerViewUtil.PAGE_SIZE = 500
var PAGE_SIZE = 200
}
var mAsyncListUtil: AsyncListUtil<Any>? = null
init {
var myViewCallback = MyViewCallback(rv)
var myDataCallback = MyDataCallback(pagingListener)
mAsyncListUtil =
AsyncListUtil(Any().javaClass, PAGE_SIZE, myDataCallback, myViewCallback)
}
fun onRangeChanged() {
mAsyncListUtil?.onRangeChanged()
}
class MyDataCallback(var listener: PagingListener) : AsyncListUtil.DataCallback<Any>() {
override fun refreshData(): Int {
return Int.MAX_VALUE
}
override fun fillData(data: Array<out Any>, startPosition: Int, itemCount: Int) {
//Log.d(MainActivity.TAG, "fillData startPosition=$startPosition itemCount=$itemCount")
listener.onFillData(data, startPosition, itemCount)
}
}
class MyViewCallback(private val recyclerView: RecyclerView) : AsyncListUtil.ViewCallback() {
fun getOutRange(rv: RecyclerView, outRange: IntArray) {
outRange[0] = (rv.layoutManager as GridLayoutManager?)!!.findFirstVisibleItemPosition()
outRange[1] = (rv.layoutManager as GridLayoutManager?)!!.findLastVisibleItemPosition()
}
override fun getItemRangeInto(outRange: IntArray) {
getOutRange(recyclerView, outRange);
//Log.d(MainActivity.TAG, "getItemRangeInto ${outRange[0]}->${outRange[1]}")
}
override fun onDataRefresh() {
//Log.d(MainActivity.TAG, "onDataRefresh")
}
override fun onItemLoaded(position: Int) {
//Log.d(MainActivity.TAG, "onItemLoaded=$position")
}
}
interface PagingListener {
fun onFillData(data: Array<out Any>, startPosition: Int, itemCount: Int) {
}
}
}