【正社員】還元率83%【フリーランス】マージン一律5万円で案件をご紹介させていただきます。 詳細はこちら

【Android】<kotlin>addOnScrollListenerを使ってリストの末尾付近で追加データを読み込む「無限スクロール (Infinite Scroll)」の実装例を紹介!

【Android】<kotlin>addOnScrollListenerを使ってリストの末尾付近で追加データを読み込む「無限スクロール (Infinite Scroll)」の実装例を紹介!
すだ

みなさまこんにちは〜!
メモリアインクのすだです。

本日は、
KotlinのaddOnScrollListenerを使用した無限スクロール機能について
実際のコードを利用して徹底解説していきます!

この記事を読んでわかること…
・無限スクロールとは?
・addOnScrollListenerとは?
・リストの末尾付近で追加データを読み込む「無限スクロール (Infinite Scroll)」の実装方法

RecyclerViewを使用したリスト表示については、以下の記事で詳しくご紹介しておりますので
ぜひ合わせてご覧ください!↓

目次

環境

  • Kotlin (ver 1.9.0)
  • Android Studio (Giraffe | 2022.3.1 Patch 3)

無限スクロールとは?

無限スクロール(Infinite Scroll)とは、
ユーザーがリストの下にスクロールすると自動的に追加のデータが読み込まれ、リストが継続的に拡張される技術です。

SNSやニュースアプリなどでよく使われており、ユーザー体験(UX)を向上させます。

addOnScrollListenerとは?

addOnScrollListener は RecyclerView にスクロールイベントを監視するリスナー(Listener:特定のイベントが発生したときに反応する仕組み)を追加するメソッドです。

これを使うことで、スクロールが一定位置に達したときに「次のデータをロードする」といった処理が可能になります。

無限スクロールの基本的な仕組み

無限スクロールの流れは以下のようになります。

  1. リストがスクロールされる。
  2. ユーザーがリストの下端に到達したとき、次のデータを自動的にロードする。
  3. ロードされたデータを既存のリストに追加して、リストが拡張される。

この動作を実現するために、RecyclerView に addOnScrollListener を設定して、
スクロール位置を監視します。

リストの末尾付近で追加データを読み込む「無限スクロール (Infinite Scroll)」の実装方法

それでは早速実装していきましょう!

1. レイアウトファイルの作成

まず、RecyclerView を含むレイアウトファイルを作成します。

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

2.  RecyclerViewにリスナーを追加

次に、RecyclerView にスクロールリスナーを追加します。

class InfiniteScrollListener(
    private val layoutManager: LinearLayoutManager,
    private val loadMore: () -> Unit
) : RecyclerView.OnScrollListener() {

    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)

        val visibleItemCount = recyclerView.childCount
        val totalItemCount = layoutManager.itemCount
        val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()

        if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount - 2) {
            loadMore()
        }
    }
}

サンプルコードの解説

1〜4行目

InfiniteScrollListenerは、RecyclerView.OnScrollListener を継承しており、RecyclerView のスクロールイベントを監視するカスタムリスナーです。

  • コンストラクタで layoutManagerRecyclerView のレイアウト管理)と、データをロードするための処理をラムダ関数 loadMore で受け取ります。
  • loadMore は、スクロールが特定の位置に達したときに実行されるデータ取得処理です。
    (APIでデータを取得するなど)

6〜7行目

onScrolled は RecyclerView がスクロールするたびに呼ばれるメソッドです。

  • dx は水平方向のスクロール量、dy は垂直方向のスクロール量を示します。
    • dy > 0 → 下方向へのスクロール
    • dy < 0 → 上方向へのスクロール
  • 下方向にスクロールしたときにのみ無限スクロールが動作するようになっています。

9〜11行目

  • visibleItemCount
    • 現在画面に表示されているアイテムの数。
    • 例えば、画面に10個のアイテムが表示されていれば 10 になります。
  • totalItemCount
    • RecyclerView に登録されているすべてのアイテム数を取得します。
    • InfiniteScrollListener()の引数に リストデータの総数を持たせてtotalItemCountとする、という方法でもよいです。
  • firstVisibleItemPosition
    • 現在画面に表示されている最初のアイテムの位置(インデックス)。
    • 例: リストがスクロールされて 5番目のアイテムが最初に表示されていれば 5 になります。

12〜14行目

visibleItemCount + firstVisibleItemPosition は、画面に表示されている最後のアイテムの位置を示します。

  • totalItemCount - 2 は、リストの末尾から2つ前のアイテム位置です。
  • この条件が成立すると、リストの末尾付近に到達したと判断して loadMore が呼ばれます。

例)
visibleItemCount = 10、firstVisibleItemPosition = 30、totalItemCount = 42 の場合:
10 + 30 = 40 で、totalItemCount – 2 = 40 なので loadMore() が呼び出されます。

3. リスナーをRecyclerViewに設定

次に、このリスナーを RecyclerView に追加します

recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = myAdapter  // ここでアダプターを設定

recyclerView.addOnScrollListener(
    InfiniteScrollListener(recyclerView.layoutManager as LinearLayoutManager) {
        fetchMoreData()  // 追加データの取得処理
    }
)

4.  メモリリークを防ぐための処理を追加

RecyclerView に addOnScrollListener を追加し続けると、メモリリーク(使い終わったリソースが解放されずメモリを消費し続ける問題)が発生する可能性があります。

これを防ぐために、不要になったリスナーをクリアする必要があります。

recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = myAdapter

// 以下の処理を追加
recyclerView.clearOnScrollListners()
recyclerView.addOnScrollListener(
    InfiniteScrollListener(recyclerView.layoutManager as LinearLayoutManager) {
        fetchMoreData()
    }
)

↑リストのデータを更新する前に、clearOnScrollListners()を置くことで
古いスクロールリスナーを削除してから新しいリスナーを追加することで 二重登録を防ぎます

fetchMoreData()はスクロールリスナー内のloadMore()にあたります。
fetchMoreDataが呼ばれるたびに指定の数だけデータを取得できる処理(ページング)を APIなどで実装してください。

それではビルドしてみましょう!

【Android】<kotlin>addOnScrollListenerを使ってリストの末尾付近で追加データを読み込む「無限スクロール (Infinite Scroll)」の実装例を紹介!

無限スクロール機能が完成しました!

まとめ

おつかれさまでした。いかがでしたでしょうか!

  • 無限スクロールは、スクロール位置に応じてデータを自動的に追加する仕組みで、ユーザー体験を向上させる
  • addOnScrollListener を使うことで、簡単に無限スクロールが実装できる
  • メモリリークを防ぐために、リスナーを適切に解除することが重要

上記ぜひ覚えて、アプリ開発で試してみてくださいね〜!

すだ

技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
を通じて、
自分の市場価値をさらに向上させてみませんか?

それではまた次の記事でお会いしましょう!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

弊社テックブログをご愛読いただきありがとうございます。
当テックブログを運用している株式会社メモリアインクは、
【正社員】還元率83%
【フリーランス】マージン一律5万円で案件のご紹介
と、エンジニアの皆様に分かりやすい形で稼げる仕組みを構築し提供させていただいております。詳しくは弊社お問い合わせページ、プロフィールのQRコードを読み取り、LINEメッセージでお問い合わせいただけますと幸いです。

コメント

コメントする

目次