RecyclerView无限滚动的实现

之前我看有人的面经问RecyclerView怎么“塞下无限个item”…(https://www.nowcoder.com/discuss/225061)
其实item肯定是有限个的,如果你想让列表一直滚不完的话,那就等快滚到底了就继续请求数据啊

不多说了,上个demo

MainActivity.kt
package name.azurefx.demo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val gen = object {
            val step = 100
            var cur = 1

            operator fun invoke(): List<MyItem> {
                val list = (cur until cur + step).map {
                    MyItem("The quick brown fox jumps over $it lazy dog${if (it > 1) "s" else ""}")
                }
                cur += step
                return list
            }
        }
        val layoutManager = LinearLayoutManager(this)
        val adapter = MyAdapter(gen().toMutableList())
        recyclerView.layoutManager = layoutManager
        recyclerView.adapter = adapter
        recyclerView.addOnScrollListener(MyScrollListener(
            layoutManager, {
                adapter.data.addAll(gen())
                adapter.notifyItemRangeInserted(adapter.data.size - gen.step, gen.step)
            }
        ))
    }
}
InfiniteScroll.kt
package name.azurefx.demo

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.my_viewholder.*

class MyAdapter(var data: MutableList<MyItem>) : RecyclerView.Adapter<MyViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.my_viewholder, parent, false)
        return MyViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) = holder.bindData(data[position])

    override fun getItemCount() = data.size
}

data class MyItem(val text: String)

abstract class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LayoutContainer {

    override val containerView: View = itemView

    abstract fun bindData(x: MyItem)
}

class MyViewHolder(itemView: View) : BaseViewHolder(itemView) {

    override fun bindData(x: MyItem) {
        textView.text = x.text
    }
}

class MyScrollListener(
    private val layoutManager: LinearLayoutManager,
    private val onLoadMore: () -> Unit,
    private val visibleThreshold: Int = 10
) : RecyclerView.OnScrollListener() {

    private var loading: Boolean = false
    private var prevCount: Int = 0

    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        val lastVisiblePos = layoutManager.findLastVisibleItemPosition()
        val itemCount = layoutManager.itemCount
        if (loading && prevCount != itemCount) loading = false
        prevCount = itemCount
        if (itemCount - lastVisiblePos - 1 < visibleThreshold) {
            if (!loading) {
                loading = true
                onLoadMore()
            }
        }
    }
}



activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    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/recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

my_viewholder.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="?android:textColorPrimary"
        android:textSize="16sp"
        tools:text="TextView" />
</LinearLayout>

效果

是不是很简单.jpg
#Android#
全部评论
还真有人用kotlin
点赞 回复 分享
发布于 2019-08-20 15:09

相关推荐

点赞 1 评论
分享
牛客网
牛客企业服务