Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Phát hiện cuộn lên/xuống ListView Android Kotlin

Hướng dẫn này minh họa cách phát hiện (detect) hướng cuộn (scroll up/down) trong ListView trên Android sử dụng Kotlin.

Bước 1: Tạo dự án mới

Mở Android Studio, chọn File → New Project và điền thông tin cần thiết.

Bước 2: Thiết kế giao diện (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>

Bước 3: Viết code MainActivity.kt

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

class MainActivity : AppCompatActivity() {
    private lateinit var listView: ListView
    private val numbers = arrayOf(
        "1", "2", "3", "4", "5", "6", "7", "8", "9", "X",
        "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(
            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,
                        "Đang cuộn xuống (Scroll Down)",
                        Toast.LENGTH_SHORT
                    ).show()
                } else if (lastFirstVisibleItem > firstVisibleItem) {
                    Toast.makeText(
                        applicationContext,
                        "Đang cuộn lên (Scroll Up)",
                        Toast.LENGTH_SHORT
                    ).show()
                }
                lastFirstVisibleItem = firstVisibleItem
            }
        })
    }
}

Bước 4: Cấu hình AndroidManifest.xml

<?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>
                
                
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Cuộn ListView lên/xuống → Toast hiển thị "Đang cuộn lên" hoặc "Đang cuộn xuống" tương ứng.

Giải thích thuật toán

  • firstVisibleItem - Index của item đầu tiên hiển thị trên màn hình
  • So sánh lastFirstVisibleItem (lần trước) với firstVisibleItem (lần hiện tại)
  • Tăng → Cuộn xuống (scroll down)
  • Giảm → Cuộn lên (scroll up)

Cải tiến: Debounce Toast (tránh spam)

private var lastToastTime = 0L
private val TOAST_DEBOUNCE = 500L // ms

override fun onScroll(...) {
    val now = System.currentTimeMillis()
    if (now - lastToastTime < TOAST_DEBOUNCE) return
    lastToastTime = now
    // show toast...
}

RecyclerView (Hiện đại hơn ListView)

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        if (dy > 0) {
            // Cuộn lên (content di chuyển lên)
        } else if (dy < 0) {
            // Cuộn xuống
        }
    }
})

Ứng dụng thực tế

  • Ẩn/hiện FloatingActionButton khi cuộn
  • Load more (pagination) khi cuộn đến cuối
  • Parallax effect cho header
  • Collapse/expand Toolbar