Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Kotlin으로 Android ListView 스크롤 방향(위·아래) 감지하는 완벽 가이드

이 튜토리얼에서는 Kotlin을 활용해 Android 앱의 ListView에서 사용자가 위로 스크롤했는지, 아래로 스크롤했는지 감지하는 방법을 단계별로 알아봅니다. ListView의 스크롤 방향을 파악하면 툴바 자동 숨김, 무한 스크롤 로딩 등 다양한 UX 기능을 구현할 수 있습니다.

핵심 원리

스크롤 방향 감지의 핵심은 AbsListView.OnScrollListeneronScroll() 콜백입니다. 화면에 보이는 첫 번째 아이템의 위치(firstVisibleItem)를 변수에 저장해 두고, 새로 전달된 값과 비교하면 됩니다.

  • 새 위치가 이전 위치보다 크면 → 아래로 스크롤 중
  • 새 위치가 이전 위치보다 작으면 → 위로 스크롤 중

1단계 — 새 프로젝트 만들기

Android Studio를 실행하고 File ⇒ New Project 메뉴로 이동한 뒤, 빈 Activity 템플릿을 선택하고 필요한 정보를 입력해 새 프로젝트를 생성합니다.

2단계 — activity_main.xml 레이아웃 작성

res/layout/activity_main.xml 파일에 아래 코드를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="8dp"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

3단계 — MainActivity.kt에 스크롤 리스너 구현

src/MainActivity.kt 파일에 아래 코드를 추가합니다. 여기서 핵심은 setOnScrollListener()를 통해 마지막으로 보였던 첫 번째 아이템 인덱스(lastFirstVisibleItem)와 현재 값을 비교하는 부분입니다.

import android.os.Bundle
import android.widget.*
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    private lateinit var listView: ListView

    private var numbers = arrayOf(
        "1", "2", "3", "4", "5",
        "6", "7", "8", "9", "10",
        "11", "12", "13", "14", "15",
        "16", "17", "18", "19", "20",
        "21", "22", "23", "24", "25"
    )

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

        val adapter: ArrayAdapter<*> = ArrayAdapter(
            this,
            R.layout.support_simple_spinner_dropdown_item,
            numbers
        )

        listView = findViewById(R.id.listView)
        listView.adapter = adapter

        listView.setOnScrollListener(object : AbsListView.OnScrollListener {
            private var lastFirstVisibleItem = 0

            override fun onScrollStateChanged(view: AbsListView, scrollState: Int) {}

            override fun onScroll(
                view: AbsListView,
                firstVisibleItem: Int,
                visibleItemCount: Int,
                totalItemCount: Int
            ) {
                if (lastFirstVisibleItem < firstVisibleItem) {
                    Toast.makeText(
                        applicationContext,
                        "리스트뷰를 아래로 스크롤하는 중",
                        Toast.LENGTH_SHORT
                    ).show()
                }
                if (lastFirstVisibleItem > firstVisibleItem) {
                    Toast.makeText(
                        applicationContext,
                        "리스트뷰를 위로 스크롤하는 중",
                        Toast.LENGTH_SHORT
                    ).show()
                }
                lastFirstVisibleItem = firstVisibleItem
            }
        })
    }
}

4단계 — AndroidManifest.xml 확인

androidManifest.xml 파일이 아래와 같이 MainActivity가 정상적으로 등록되어 있는지 확인합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.q11">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

앱 실행 및 결과 확인

실제 Android 기기를 컴퓨터에 연결한 상태라고 가정하고 진행합니다. Android Studio에서 프로젝트의 Activity 파일을 연 뒤, 툴바의 Run(실행) 버튼을 클릭하세요. 실행 기기 목록에서 본인의 모바일 기기를 선택하면, 기기 화면에 숫자 리스트가 표시됩니다.

이제 리스트를 손가락으로 위아래로 밀어보세요. 스크롤 방향에 따라 화면 하단에 "리스트뷰를 아래로 스크롤하는 중" 또는 "리스트뷰를 위로 스크롤하는 중"이라는 토스트 메시지가 나타나는 것을 확인할 수 있습니다.

마무리 및 추가 팁

이처럼 firstVisibleItem 값의 변화만 추적하면 별도의 제스처 라이브러리 없이도 간단히 스크롤 방향을 감지할 수 있습니다. 실무에서는 토스트 대신 툴바를 숨기거나(hide()/show()), 플로팅 버튼(FAB)을 표시·숨김 처리하는 방식으로 응용하는 경우가 많습니다. 또한 최신 프로젝트라면 ListView보다 성능과 유연성이 뛰어난 RecyclerView를 사용하는 것도 고려해 보세요. RecyclerView에서도 동일한 원리로 onScrolled() 콜백에서 스크롤 방향을 감지할 수 있습니다.