Android RecyclerView paging/pager/page implements based on AsyncListUtil,kotlin

Android RecyclerView paging/pager/page implements based on AsyncListUtil,kotlin

 

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
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
    companion object {
        val TAG = "test-log"
    }

    //假设已经知道全量数据,后续的分段是把源数据一片一片的截出来,装到新的分页数据集里面
    val ITEMS = ArrayList<MyData>()
    var COUNT = 0

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

        var mRecyclerView: RecyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        mRecyclerView?.layoutManager = GridLayoutManager(this, 3).apply {
            orientation = GridLayoutManager.VERTICAL
        }

        val mAdapter = MyAdapter()
        mRecyclerView?.adapter = mAdapter

        MyPagingRecyclerViewUtil.PAGE_SIZE = 50
        var mRecyclerViewUtil = MyPagingRecyclerViewUtil(mRecyclerView!!,
            object : MyPagingRecyclerViewUtil.PagingListener {
                override fun onFillData(
                    data: Array<out Any>, startPosition: Int, itemCount: Int
                ) {
                    Log.d(TAG, "onFillData $startPosition $itemCount")
                    fillData(startPosition, itemCount)
                }

                override fun onVisibleRange(fromPos: Int, toPos: Int) {
                    Log.d(TAG, "onVisibleRange $fromPos $toPos ${ITEMS.size}")
                }

                override fun refreshData(): Int {
                    return ITEMS.size
                }
            })

        mRecyclerView?.addOnScrollListener(object : OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                mRecyclerViewUtil?.onRangeChanged()
            }
        })

        CoroutineScope(Dispatchers.IO).launch {
            repeat(Int.MAX_VALUE) {
                ITEMS.clear()

                COUNT = (200..400).random()
                //COUNT=201
                for (i in 0 until COUNT) {
                    var data = MyData("-$COUNT-")
                    ITEMS.add(data)
                }

                //触发onFillData()
                mRecyclerViewUtil?.refresh()
                delay(20) //如果不时延,新数据不能实时更新到UI

                runOnUiThread {
                    mAdapter.onChange(ITEMS)

                    //RecyclerView启动后默认滚到最底部
                    //mRecyclerView?.scrollToPosition(mAdapter.getItemCount() - 1)
                }

                //模拟下一批新数据在此时间后到
                delay(5000)
            }
        }
    }

    fun fillData(startPosition: Int, itemCount: Int) {
        var pos = 0
        for (i in 0 until itemCount) {
            pos = startPosition + i
            ITEMS.set(pos, MyData("$startPosition $i -$COUNT ${System.currentTimeMillis()}"))
        }
    }
}
<?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.util.Log
import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.recyclerview.widget.AsyncListUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView


class MyPagingRecyclerViewUtil(rv: RecyclerView, pagingListener: PagingListener) {
    companion object {
        var PAGE_SIZE = 200
    }

    private var mAsyncListUtil: AsyncListUtil<Any>? = null

    init {
        var viewCallback = PagingViewCallback(rv, pagingListener)
        var dataCallback = PageingDataCallback(pagingListener)
        mAsyncListUtil =
            AsyncListUtil(Any().javaClass, PAGE_SIZE, dataCallback, viewCallback)
    }

    fun onRangeChanged() {
        mAsyncListUtil?.onRangeChanged()
    }

    fun refresh(){
        Log.d(MainActivity.TAG,"refresh")
        mAsyncListUtil?.refresh()
    }

    private class PageingDataCallback(var listener: PagingListener) :
        AsyncListUtil.DataCallback<Any>() {

        //如果RecyclerView的数据源总长度发生变化,需要更新这个值,否则getItemRangeInto不会触发新的可视区域range更新。
        override fun refreshData(): Int {
            return listener?.refreshData() ?: 0
        }

        @WorkerThread
        override fun fillData(data: Array<out Any>, startPosition: Int, itemCount: Int) {
            listener?.onFillData(data, startPosition, itemCount)
        }
    }

    private class PagingViewCallback(val recyclerView: RecyclerView, var listener: PagingListener) :
        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);
            listener?.onVisibleRange(outRange[0], outRange[1])
        }

        override fun onDataRefresh() {

        }

        override fun onItemLoaded(position: Int) {

        }
    }


    interface PagingListener {
        @WorkerThread
        fun onFillData(data: Array<out Any>, startPosition: Int, itemCount: Int) {

        }

        @UiThread
        fun onVisibleRange(fromPos: Int, toPos: Int) {

        }

        fun refreshData(): Int {
            return 0
        }
    }
}
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.MainThread
import androidx.recyclerview.widget.RecyclerView

class MyAdapter() : RecyclerView.Adapter<MyViewHolder>() {
    var items: ArrayList<MyData>? = ArrayList()

    @MainThread
    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(R.layout.item, parent, false)
        return MyViewHolder(view)
    }

    override fun getItemCount(): Int {
        return items?.size!!
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.pos.text = "$position"
        holder.text.text = items?.get(position)?.str
    }
}

class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val pos: TextView = itemView.findViewById(R.id.pos)
    val text: TextView = itemView.findViewById(R.id.text)
}

data class MyData(var str: String)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="5dp"
    android:paddingBottom="5dp">

    <TextView
        android:id="@+id/pos"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textSize="12dp" />

</LinearLayout>

9576f75a2b9f44bc8855df9c107c5313.png

扫描二维码关注公众号,回复: 15176103 查看本文章

Android RecyclerView page/paging load,kotlin(3)_zhangphil的博客-CSDN博客基于Android官方Paging Library的RecyclerView分页加载框架我之前写了一篇RecyclerView分页加载机制的文章,是基于Android官方的AsyncListUtil实现的,详情见附录文章1。基于Android官方Paging Library的RecyclerView分页加载框架我之前写了一篇RecyclerView分页加载机制的文章,是基于Android官方的AsyncListUtil实现的,详情见附录文章1。【代码】Android Paging 3,kotlin(1)https://blog.csdn.net/zhangphil/article/details/130784241

Android Paging3/Page3 Cursor query segment photo into 3 grid RecyclerView,kotlin (2)_zhangphil的博客-CSDN博客基于Android官方Paging Library的RecyclerView分页加载框架我之前写了一篇RecyclerView分页加载机制的文章,是基于Android官方的AsyncListUtil实现的,详情见附录文章1。Android Paging Library是Android官方support。基于Android官方Paging Library的RecyclerView分页加载框架_android setmainthreadexecutor_zhangphil的博客-CSDN博客。https://blog.csdn.net/zhangphil/article/details/130751993

Android Paging 3 Flow or LiveData,kotlin(1)_zhangphil的博客-CSDN博客【代码】Android Paging 3,kotlin(1)https://blog.csdn.net/zhangphil/article/details/130735753

Android Room联合AsyncListUtil实现RecyclerView分页加载ORM数据_zhangphil的博客-CSDN博客Android Room联合AsyncListUtil实现RecyclerView分页加载ORM数据我之前写了一系列关于AsyncListUtil实现RecyclerView和ListView的分页加载机制和技术路线,见附录文章4,5。同时也写了一些列文章介绍Android官方推出的ORM数据库:Room技术,见附录文章1,2。现在结合Android分页加载框架AsyncListUtil,以及Anhttps://blog.csdn.net/zhangphil/article/details/78661838

基于Android官方AsyncListUtil优化改进RecyclerView分页加载机制(一)_recyclerview 分页机制_zhangphil的博客-CSDN博客基于Android官方AsyncListUtil优化改进RecyclerView分页加载机制(一)Android AsyncListUtil是Android官方提供的专为列表这样的数据更新加载提供的异步加载组件。基于AsyncListUtil组件,可以轻易实现常见的RecyclerView分页加载技术。AsyncListUtil技术涉及的细节比较繁复,因此我将分别写若干篇文章,分点、分解Asynchttps://blog.csdn.net/zhangphil/article/details/78603499

猜你喜欢

转载自blog.csdn.net/zhangphil/article/details/130874429