Kotlinを勉強している中で、SwipeRefreshLayoutとScrollViewを同時に使用した際に、スクロールが競合してしまう現象が発生しました。
解決できたので、備忘録として記録しておきます。
結論
ScrollViewをNestedScrollViewに置き換えた。
経緯
冒頭で書いた通り、SwipeRefreshLayoutとScrollViewを同時に使用した際に、スクロールが競合してしまいました。
SwipeRefreshLayoutとかScrollViewってなんや?という方は、ここでは省略させていただきますので、別途調べていただけると幸いです。
- 具体的に何が起きたか?
レイアウトの都合上、SwipeRefreshLayoutの入れ子でScrollViewを配置していました。
ところが…
ScrollViewの領域でも、上から下にスワイプをすると、SwipeRefreshLayoutの機能のほうが優先されて動いてしまい、ScrollViewのスクロールが一方通行になってしまっていました。
解決
ドラえもんよろしくChatGPTに泣きついたところ、
「NestedScrollViewを使いなさい」
と教えてもらいました。
NestedScrollViewとは(以下ChatGPTより引用)
NestedScrollViewは、Androidのサポートライブラリの一部であるScrollViewの拡張版です。NestedScrollViewは内部的にネスト可能なスクロール動作をサポートしているため、複数のスクロール可能なビューが組み合わさっている(つまり、ネストされている)場合でも適切に動作します。これは特に、スクロール可能な子ビューが含まれるCoordinatorLayoutなどのコンテキストで便利です。
NestedScrollViewは以下のように使用します:
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Child views here -->
</androidx.core.widget.NestedScrollView>`
NestedScrollViewは1つの直接の子ビューのみをサポートします。そのため、複数のビューをスクロールする必要がある場合は、それらのビューをLinearLayoutやRelativeLayoutなどのビューグループに包む必要があります。
NestedScrollViewは、スクロールイベントを親ビューと共有することをサポートしているため、スクロールイベントに応じて他のビュー(例えば、AppBarLayout)の動作を変更したい場合に特に便利です。
ただし、大量のビューまたは非常に大きなビュー階層をスクロール可能にする場合は、代わりに
RecyclerViewを使用することを検討してください。RecyclerViewは、画面外のビューを再利用することでメモリ効率を大幅に向上させることができます。
====引用ここまで====
言われたと通り、ScrollViewをNestedScrollViewに置き換えてみると…
う、動く!!動くぞ!!
きちんと入れ子部分を上下にスクロールすることができました。
置き換えるだけで動くようになるとは……これは助かりますね!
締め
まだKotlinを触り始めたばかりで、
「何でそうなるの??!」「さっぱりわからん」
ということが多いですが、触りながら学びながら、もっとグリグリといじれるようになっていきたいです。
スクロールの競合について、どなたかの助けになれば幸いです。
ではまた。