web-dev-qa-db-ja.com

Androidサポートライブラリv24.0.0でプログラムでAppBarLayoutの高さを設定するにはどうすればよいですか?

Androidサポートライブラリv23.4.0からv24.0.0にアップグレードすると、プログラムで標高を0に設定してAppBarLayoutが機能しなくなりました。

appBayLayout.setElevation(0);

XMLで標高を設定するときに機能します。

19
bryant1410

編集

V24.0.0のAppBarLayoutは、状態に応じて標高を定義するStateListAnimatorを使用します。したがって、setElevationが使用されている場合、StateListAnimatorを使用しても効果はありません(これはデフォルトで発生します)。 XMLまたはプログラムでelevationを設定します(両方ともAPI> = 21の場合)。

StateListAnimator stateListAnimator = new StateListAnimator();
stateListAnimator.addState(new int[0], ObjectAnimator.ofFloat(view, "elevation", 0));
appBarLayout.setStateListAnimator(stateListAnimator);

古い答え

これは 設計サポートライブラリの問題 のようです。この問題は、setElevationを使用してプログラムで標高を設定する方法に関連しています。 XMLから設定すると、ビューにStateListAnimatorが配置され、setElevationは呼び出されません。ただし、setElevationは機能するはずです。

ここに回避策があります:

setDefaultAppBarLayoutStateListAnimator(appBarLayout, 0);

@SuppressLint("PrivateResource")
private static void setDefaultAppBarLayoutStateListAnimator(final View view, final float targetElevation) {
    final StateListAnimator sla = new StateListAnimator();

    // Enabled, collapsible and collapsed == elevated
    sla.addState(new int[]{Android.R.attr.enabled, Android.support.design.R.attr.state_collapsible,
            Android.support.design.R.attr.state_collapsed},
            ObjectAnimator.ofFloat(view, "elevation", targetElevation));

    // Enabled and collapsible, but not collapsed != elevated
    sla.addState(new int[]{Android.R.attr.enabled, Android.support.design.R.attr.state_collapsible,
            -Android.support.design.R.attr.state_collapsed},
            ObjectAnimator.ofFloat(view, "elevation", 0f));

    // Enabled but not collapsible == elevated
    sla.addState(new int[]{Android.R.attr.enabled, -Android.support.design.R.attr.state_collapsible},
            ObjectAnimator.ofFloat(view, "elevation", targetElevation));

    // Default, none elevated state
    sla.addState(new int[0], ObjectAnimator.ofFloat(view, "elevation", 0));

    view.setStateListAnimator(sla);
}

これは、v24.0.0のクラスViewUtilsLollipopのメソッドを呼び出して、コンストラクターが行うことから取得されます。

26
bryant1410

これに対するもう1つの可能な解決策は、以下に示すように、AppBarLayoutAndroid:stateListAnimator="@null"を追加することです。

<Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:stateListAnimator="@null"
        Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

私の場合、実行時にAppBarLayoutの標高を変更する必要があり、setElevation(..)がそのトリックを実行しました。

ただし、画面を回転してonCreateOptionMenuからsetElevation(..)を呼び出した後は機能しませんでしたが、setStateListAnimator(null)はうまくいきました。

したがって、私はこのロジックを取得しました:

public final float appBarElevation = 10.5f;

public void disableAppBarElevation() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        appBarLayout.setElevation(0);
        appBarLayout.setStateListAnimator(null);
    }
}

public void enableAppBarElevation() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        appBarLayout.setElevation(appBarElevation);
    }
}
0
Johnny Five