You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中FirestoreRecyclerAdapter实现Firestore分页求示例代码

Firestore Pagination with FirestoreRecyclerAdapter in Android

Got it, let’s put together a complete, working example for implementing Firestore pagination with FirestoreRecyclerAdapter in your Android ListActivity. Based on your goal of loading 25 teachers per page using query cursors, here’s how to make it happen:

1. Define Your Data Class

First, create a Teacher data class that matches the structure of your Firestore documents:

// Teacher.kt
data class Teacher(
    val name: String? = null,
    val subject: String? = null,
    // Add any other fields from your Firestore teacher documents here
)

2. Full ListActivity Implementation

Here’s the complete code for your ListActivity, including pagination logic, RecyclerView setup, and cursor handling:

class ListActivity : AppCompatActivity() {
    private lateinit var firestore: FirebaseFirestore
    private lateinit var teacherAdapter: FirestoreRecyclerAdapter<Teacher, TeacherViewHolder>
    private var lastVisibleDoc: DocumentSnapshot? = null
    private val PAGE_LIMIT = 25 // Number of items per page

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

        // Initialize Firestore instance
        firestore = FirebaseFirestore.getInstance()

        // Set up RecyclerView
        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.setHasFixedSize(true)

        // Build initial query: first 25 teachers, ordered by name (adjust the order field as needed)
        val initialQuery = firestore.collection("teachers")
            .orderBy("name") // Ensure this field has a Firestore index (create if prompted)
            .limit(PAGE_LIMIT.toLong())

        // Configure FirestoreRecyclerOptions
        val adapterOptions = FirestoreRecyclerOptions.Builder<Teacher>()
            .setQuery(initialQuery, Teacher::class.java)
            .build()

        // Initialize the adapter
        teacherAdapter = object : FirestoreRecyclerAdapter<Teacher, TeacherViewHolder>(adapterOptions) {
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TeacherViewHolder {
                val itemView = LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_teacher, parent, false)
                return TeacherViewHolder(itemView)
            }

            override fun onBindViewHolder(holder: TeacherViewHolder, position: Int, teacher: Teacher) {
                // Bind teacher data to your ViewHolder views
                holder.tvName.text = teacher.name
                holder.tvSubject.text = teacher.subject

                // Track the last visible document when we reach the end of the current page
                if (position == itemCount - 1) {
                    lastVisibleDoc = snapshots.getSnapshot(position)
                }
            }
        }

        recyclerView.adapter = teacherAdapter

        // Add scroll listener to trigger load more when near the bottom
        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)

                val layoutManager = recyclerView.layoutManager as LinearLayoutManager
                val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()

                // Load next page if we're at the last item and have a cursor to start from
                if (lastVisiblePosition == teacherAdapter.itemCount - 1 && lastVisibleDoc != null) {
                    loadNextPage()
                }
            }
        })
    }

    private fun loadNextPage() {
        // Build query for next page, starting after the last visible document
        val nextPageQuery = firestore.collection("teachers")
            .orderBy("name")
            .startAfter(lastVisibleDoc)
            .limit(PAGE_LIMIT.toLong())

        // Update adapter with new query options
        val newAdapterOptions = FirestoreRecyclerOptions.Builder<Teacher>()
            .setQuery(nextPageQuery, Teacher::class.java)
            .build()

        teacherAdapter.updateOptions(newAdapterOptions)
        // Note: FirestoreRecyclerAdapter replaces the dataset by default. If you want to append items instead, you'll need a custom adapter that manages a combined list.
    }

    // ViewHolder class for your RecyclerView items
    class TeacherViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvName: TextView = itemView.findViewById(R.id.tv_teacher_name)
        val tvSubject: TextView = itemView.findViewById(R.id.tv_teacher_subject)
    }

    // Start/stop listening for Firestore updates
    override fun onStart() {
        super.onStart()
        teacherAdapter.startListening()
    }

    override fun onStop() {
        super.onStop()
        teacherAdapter.stopListening()
    }
}

3. Key Notes & Setup Tips

  • Index Requirement: The field you use for orderBy (e.g., name) needs a Firestore composite index. If you run the app and get an error about missing indexes, follow the link in the logcat to create it automatically.
  • Dependencies: Make sure you have these dependencies in your module-level build.gradle file (check for the latest versions):
    implementation 'com.google.firebase:firebase-firestore-ktx:24.10.0'
    implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
    
  • Appending vs Replacing: The example above replaces the RecyclerView dataset when loading a new page. If you want to append items (keep previous pages visible), you’ll need to use a custom RecyclerView.Adapter that maintains a single list and adds new items to it, instead of relying on FirestoreRecyclerAdapter’s built-in dataset replacement.

内容的提问来源于stack exchange,提问作者Sudhakar R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:16:53