CollapsingToolbarLayout の状態変更を使いやすくする
はじめに
今回は、CollapsingToolbarLayout を使うときに便利なリスナーを紹介します。
CollapsingToolbarLayoutの基本的な実装については説明しないので、xmlの組み方については公式ページでも見てください。
AppBarLayoutをカスタム
CollapsingToolbarLayoutはAppBarLayout内で定義しますが、実際にCollapsingToolbarLayoutが閉じている状態(Collapse)なのか開いている状態(Expand)なのかということがわかりにくいです。
そこで以下のような Kotlin Extension を用意して、実装していきましょう。
/** * AppBarLayoutのスクロール状態 */ sealed class AppBarLayoutScrollState { /** * スクロールされて閉じている状態 */ object Expanded : AppBarLayoutScrollState() /** * スクロールされて開いている状態 */ object Collapsed : AppBarLayoutScrollState() /** * スクロール途中の状態 * * @property percentage スクロール比率(Expandedを1.0としてCollapsedを0.0とする) */ data class Scrolling( @FloatRange(from = 0.0, to = 1.0) val percentage: Float ) : AppBarLayoutScrollState() } /** * AppBarLayoutのスクロール状態を監視するリスナーを設定 * * @param listener リスナー */ fun AppBarLayout.setOnChangedAppBarScrollStateListener(listener: (AppBarLayoutScrollState) -> Unit) { addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset -> when (abs(verticalOffset)) { 0 -> { // Expanded listener(AppBarLayoutScrollState.Expanded) listener(AppBarLayoutScrollState.Scrolling(1f)) } appBarLayout.totalScrollRange -> { // Collapsed listener(AppBarLayoutScrollState.Collapsed) listener(AppBarLayoutScrollState.Scrolling(0f)) } else -> { // Scrolling val scrollPercentage = 1 - abs(verticalOffset / appBarLayout.totalScrollRange.toFloat()) listener(AppBarLayoutScrollState.Scrolling(scrollPercentage)) } } }) }
これを使用することで、
開閉に合わせてFABを表示・非表示を切り替えたり、
スクロールに合わせて、画像をフェードアウトさせたりということが可能になります!!
// AppBarLayout appBarLayout.setOnChangedAppBarScrollStateListener { when (it) { is AppBarLayoutScrollState.Expanded -> { // スクロールで開いた時 fab.show() } is AppBarLayoutScrollState.Collapsed -> { // スクロールで閉じた時 fab.hide() } is AppBarLayoutScrollState.Scrolling -> { // スクロール中 imageView.alpha = it.percentage } } }