How to set the elevation of an AppBarLayout programmatically in the Android Support Library v24.0.0?

余生长醉 提交于 2019-12-18 02:12:11

问题


When upgrading from the Android Support Library v23.4.0 to v24.0.0, setting the elevation to 0 programmatically to an AppBarLayout stopped working:

appBayLayout.setElevation(0);

It does work when setting the elevation in the XML.


回答1:


Edit

The AppBarLayout from v24.0.0 uses a StateListAnimator that defines the elevation depending on its state. So using setElevation will have no effect if a StateListAnimator is being used (which happens by default). Set the elevation via the XML or programmatically (both for API >= 21):

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

Old answer

This seems to be an issue of the design support library. The problem is related to the way the elevation is set programmatically, using setElevation. Setting it from the XML is placing a StateListAnimator in the view and not calling setElevation. However, setElevation should work.

Here there is a workaround:

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);
}

This is taken from what the constructor does, calling a method in the class ViewUtilsLollipop in v24.0.0.




回答2:


One more possible solution for this is to add android:stateListAnimator="@null" to your AppBarLayout as shown below.

<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">



回答3:


In my case I needed to change elevation of AppBarLayout in runtime and setElevation(..) did the trick.

However after screen rotation and calling setElevation(..) from onCreateOptionMenu didn't work, but setStateListAnimator(null) did the trick.

Therefore I got this logic:

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);
    }
}


来源:https://stackoverflow.com/questions/37992365/how-to-set-the-elevation-of-an-appbarlayout-programmatically-in-the-android-supp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!