Android RecyclerView 스크롤 최상단/최하단 감지 방법

✨ 개요

RecyclerView는 대용량 리스트를 효율적으로 표현할 수 있는 대표적인 컴포넌트입니다.
사용자의 스크롤이 최상단 또는 최하단에 도달했는지 감지하면 아래와 같은 기능에 응용할 수 있습니다:


1. ✅ 기본 원리

RecyclerViewaddOnScrollListener()를 사용하여 스크롤 이벤트를 감지할 수 있습니다.
LinearLayoutManager와 함께 사용하여 스크롤 위치와 아이템 개수를 기준으로 최하단/최상단 도달 여부를 확인합니다.

2. ✅ 전체 예제 코드

2.1 레이아웃 파일

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp" />

2.2 SimpleStringAdapter 코드

import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class SimpleStringAdapter(private val items: List<String>) :
  RecyclerView.Adapter<SimpleStringAdapter.ViewHolder>() {

  inner class ViewHolder(private val view: TextView) : RecyclerView.ViewHolder(view) {
    fun bind(item: String) {
      view.text = item
    }
  }

  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val textView = TextView(parent.context).apply {
      setPadding(24, 32, 24, 32)
      textSize = 18f
    }
    return ViewHolder(textView)
  }

  override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.bind(items[position])
  }

  override fun getItemCount(): Int = items.size
}

2.3 MainActivity 코드

import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.js.sample.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

  private lateinit var binding: ActivityMainBinding

  private val TAG: String = "MainActivity"

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // 샘플 데이터
    val items = (1..50).map { "Item $it" }
    val adapter = SimpleStringAdapter(items)
    val layoutManager = LinearLayoutManager(this)

    binding.recyclerView.layoutManager = layoutManager
    binding.recyclerView.adapter = adapter

    binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
      override fun onScrolled(rv: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(rv, dx, dy)

        val totalItemCount = layoutManager.itemCount
        val lastVisibleItem = layoutManager.findLastCompletelyVisibleItemPosition()
        val firstVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition()

        if (firstVisibleItem == 0) {
          Toast.makeText(this@MainActivity, "🔝 최상단입니다", Toast.LENGTH_SHORT).show()
        }

        if (lastVisibleItem == totalItemCount - 1) {
          Toast.makeText(this@MainActivity, "🔚 최하단입니다", Toast.LENGTH_SHORT).show()
        }
      }
    })
  }
}

3.💡 팁 & 참고사항

❗ 최하단 감지 시점을 이용해 “무한 스크롤” 구현에도 사용할 수 있습니다.


4.🧠 결론



Related Posts