みなさまこんにちは〜!
メモリアインクのすだです。
本日は、
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:特定のイベントが発生したときに反応する仕組み)を追加するメソッドです。
これを使うことで、スクロールが一定位置に達したときに「次のデータをロードする」といった処理が可能になります。
無限スクロールの基本的な仕組み
無限スクロールの流れは以下のようになります。
- リストがスクロールされる。
- ユーザーがリストの下端に到達したとき、次のデータを自動的にロードする。
- ロードされたデータを既存のリストに追加して、リストが拡張される。
この動作を実現するために、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 のスクロールイベントを監視するカスタムリスナーです。
- コンストラクタで
layoutManager(RecyclerViewのレイアウト管理)と、データをロードするための処理をラムダ関数loadMoreで受け取ります。 loadMoreは、スクロールが特定の位置に達したときに実行されるデータ取得処理です。
(APIでデータを取得するなど)
6〜7行目
onScrolled は RecyclerView がスクロールするたびに呼ばれるメソッドです。
dxは水平方向のスクロール量、dyは垂直方向のスクロール量を示します。dy > 0→ 下方向へのスクロールdy < 0→ 上方向へのスクロール
- 下方向にスクロールしたときにのみ無限スクロールが動作するようになっています。
9〜11行目
visibleItemCount- 現在画面に表示されているアイテムの数。
- 例えば、画面に10個のアイテムが表示されていれば
10になります。
totalItemCountRecyclerViewに登録されているすべてのアイテム数を取得します。- 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などで実装してください。
それではビルドしてみましょう!


無限スクロール機能が完成しました!
まとめ
おつかれさまでした。いかがでしたでしょうか!
- 無限スクロールは、スクロール位置に応じてデータを自動的に追加する仕組みで、ユーザー体験を向上させる
addOnScrollListenerを使うことで、簡単に無限スクロールが実装できる- メモリリークを防ぐために、リスナーを適切に解除することが重要
上記ぜひ覚えて、アプリ開発で試してみてくださいね〜!
技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】![]()
![]()
自分の市場価値をさらに向上させてみませんか?
それではまた次の記事でお会いしましょう!










コメント