😽
【Android】(Kotlin)recyclerViewの特定の要素が表示されたら処理を行う
基本方針
- アダプターに「特定の要素の位置」を保存する
- onScrolled()をオーバーライドし、スクロールの度に判断を行う
- 「最後に表示されている要素の位置」が「特定の要素の位置」に到達したら処理を実行する
コードと解説
まずは、特定の要素の位置をアダプター内部で保持します。
// アダプターに渡すデータのリストをlistとしています。
val list = {...}
var position: Int
get() {
var value = -1
list.forEachIndexed { index, item ->
// ここで特定の要素の判別を行う(以下はtitleで判別する場合の例)
if (item.title == "hoge") value = index
}
return value
}
次に、RecyclerViewのOnScrollListener()内、onScrolled()をオーバーライドします。
RecyclerViewの表示処理を行うFragment内部に
private val onScrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
// RecyclerViewの要素をrecyclerItemとして定義してください。
val recyclerItem = binding.hogeRecyclerItem
val linearLayoutManager = recyclerItem.layoutManager as LinearLayoutManager
val lastVisibleItem = linearLayoutManager.findLastCompletelyVisibleItemPosition()
// ここに条件判定を入れる(adapterは上で定義したものを参照できるようにしておいてください。)
if (lastVisibleItem >= adapter.position) {
// ここに実行したい処理を入れる
}
}
}
注意点
条件分岐の中で
if (lastVisibleItem >= adapter.position)
という記述がありますが、ここは==にすると高速にスクロールした時に処理が呼ばれない可能性があります。
そのため、「表示され終わった要素の位置」が「トリガーにしたい要素の位置」以上となるように記述しています。
スクロール速度を制限する方法もありますが、ユーザーインターフェイスに悪影響を及ぼす可能性があるため、避けるべきです。
Discussion