LoginSignup
23
15

More than 5 years have passed since last update.

StateListAnimatorを使ってスクロール時にToolbarのelevationを変化させる

Posted at

Overview

test.gif

Toolbarの下のScrollViewやRecyclerViewをスクロールした時にToolbarの影をつけたい時の実装です。
ToolbarのStateListAnimatorと、ScrollViewのcanScrollVertically()を使って実現します。

1. ObjectAnimatorを作る

状態がselectedになった時にelevationを変化させるObjectAnimatorを作ります。

res/animator/toolbar_elevation.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true">
        <objectAnimator
            android:duration="200"
            android:propertyName="elevation"
            android:valueTo="4dp"
            android:valueType="floatType" />
    </item>

    <item>
        <objectAnimator
            android:duration="200"
            android:propertyName="elevation"
            android:valueTo="0dp"
            android:valueType="floatType" />
    </item>

</selector>

2. ToolbarにObjectAnimatorをセットする

作成したObjectAnimatorをToolbarにセットします。

res/layout/{layout_name}.xml
<androidx.appcompat.widget.Toolbar
    ...
    android:stateListAnimator="@animator/toolbar_elevation" />

3. Toolbarの状態を変更する

ScrollView/RecyclerViewのcanScrollVertically()の値でToolbarの状態を変更します。

ActivityorFragment.kt
binding.scrollView.viewTreeObserver.addOnScrollChangedListener {
    // -1をセットすると、スクロール位置が一番上の時のみtrueになる
    isSelected = binding.scrollView.canScrollVertically(-1)
}

これでスクロール時にToolbarの選択状態が変わり、elevationが変化するようになります。


DataBinding Tips

styleとDataBindingのCustomBindingAdapterを使って共通化することもできます。

res/values/styles.xml
<style name="Toolbar.NoShadow" parent="Widget.AppCompat.Toolbar">
    <item name="android:elevation">0dp</item>
    <item name="android:stateListAnimator">@animator/toolbar_elevation</item>
</style>
ToolbarBindingAdapters.kt
@BindingAdapter("shadowAnimationScrollViewId")
fun Toolbar.setShadowAnimationScrollViewId(@IdRes scrollViewId: Int) {
    val scrollView = this.rootView.findViewById<View>(scrollViewId)
    if (scrollView is ScrollView) {
        scrollView.viewTreeObserver.addOnScrollChangedListener {
            isSelected = scrollView.canScrollVertically(-1)
        }
    }
}
layout/{layout}.xml
<android.support.v7.widget.Toolbar
    ...
    style="@style/Toolbar.NoShadow"
    app:shadowAnimationScrollViewId="@{R.id.scroll}" />

<ScrollView
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    ...
</ScrollView>
23
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
15