如何在所有Android版本上显示支持库的ActionBar和工具栏的阴影?

and*_*per 15 android android-actionbar android-support-library android-elevation

这是一个简单的问题:

我使用新的支持库,它允许我拥有一个工具栏实例,甚至将其设置为活动的actionBar(或使用默认的).

如何自定义工具栏(或默认ActionBar)投射的阴影?

我试过使用"setElevation"(两者都有),但它似乎没有在Android Lollipop上做任何事情.

另外,我找不到如何在Lollipop前版本上自定义阴影.可能有这个API吗?或至少是一个drawable(我没有找到,即使我已经尝试过)?


好的,我已经设法找到了下一件事:

对于Lollipop和pre-Lollipop,当您的活动使用正常的AppCompat主题(例如"Theme.AppCompat.Light")时,阴影应该看起来很好.

但是,当您使用"setSupportActionBar"(并使用适当的主题,例如"Theme.AppCompat.Light.NoActionBar")时,您将遇到阴影的一些问题.

对于pre-Lollipop,你可以在工具栏下面放置一个FrameLayout,它看起来就像用于普通主题的那样,如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:foreground="?android:windowContentOverlay"
        android:visibility="@integer/action_bar_shadow_background_visibility" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:text="@string/hello_world" />

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

您可以使用FrameLayout作为活动的内容,或使用我所做的.您还可以通过为棒棒糖前置整数0和为棒棒糖及以上版本放置2来设置其可见性,就像我使用"action_bar_shadow_background_visibility"一样.

这是一个丑陋的解决方案,但它可以工作,但仅限于前Lollipop版本.

在任何情况下,如果我使用"setSupportActionBar",我仍然无法找到一种方法来为Lollipop显示阴影.我尝试在工具栏和操作栏上使用"setElevation"(在调用"setSupportActionBar"之后立即使用"getSupportActionBar").

我也没有得到如何获得动作栏的标准高度,因为我注意到许多教程说使用"minHeight"作为工具栏.非常感谢这方面的帮助.

谁能帮我这个?

再说一次,为了说清楚,这就是我的要求:

  • 对于Pre-Lollipop,显示在工具栏和ActionBar的支持库上使用的相同阴影.
  • 棒棒糖也一样(但是使用棒棒糖的那个)
  • 额外:在Lollipop上自定义阴影更加"精致"(也许可以在所有版本上自定义).
  • 额外:为什么工具栏的minHeight获取操作栏高度的值,而不是高度本身?

编辑:好的,到目前为止,这是模仿Lollipop的影子:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />

    <include
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        layout="@layout/toolbar_action_bar_shadow" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:text="@string/hello_world" />

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

RES /布局/ toolbar_action_bar_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:foreground="?android:windowContentOverlay" />
Run Code Online (Sandbox Code Playgroud)

RES /布局-V21/toolbar_action_bar_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/msl__action_bar_shadow" />
Run Code Online (Sandbox Code Playgroud)

RES /抽拉-V21/RES /布局/ msl__action_bar_shadow.xml

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

    <!-- intended for lollipop and above -->

    <item>
        <shape
            android:dither="true"
            android:shape="rectangle" >
            <gradient
                android:angle="270"
                android:endColor="#00000000"
                android:startColor="#33000000" />

            <size android:height="10dp" />
        </shape>
    </item>

</layer-list>
Run Code Online (Sandbox Code Playgroud)

它不完全相同,但它是相似的.


编辑:我仍然不知道为什么会这样.我认为我在这个问题上写的代码是误导性的,因为所有要做的就是设置背景.然而在我正在测试它的应用程序仍然无济于事.我正在尝试修复的应用程序在导航抽屉上方有工具栏.

有一会儿,我认为可能是因为我制作了一个自定义工具栏(从工具栏扩展)并更改了其alpha值(根据导航抽屉),但即使我使用普通工具栏并禁用所有相关的内容到alpha,它仍然无法正常工作.此外,不仅如此,而且在一个全新的项目中,我试图为工具栏设置半透明背景,并根据"setElevation"方法得到阴影.

现在我更难找到导致这个问题的原因,因为它似乎不是因为透明度而不是因为自定义工具栏类......

这是包含工具栏的活动的布局,以防这可能有任何帮助:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/activity_main__drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <FrameLayout
            android:id="@+id/activity_main__fragmentContainer"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <include
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="left"
            android:layout_marginTop="?attr/actionBarSize"
            layout="@layout/activity_main__sliding_menu" />
    </android.support.v4.widget.DrawerLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <com.app.ui.Toolbar
            android:id="@+id/activity_main__toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:layoutDirection="ltr"
            android:minHeight="?attr/actionBarSize"
            app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            tools:ignore="UnusedAttribute" />

        <!-- <include -->
        <!-- android:layout_width="match_parent" -->
        <!-- android:layout_height="wrap_content" -->
        <!-- layout="@layout/toolbar_action_bar_shadow" /> -->
    </LinearLayout>

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

Jer*_*ols 14

据我所知/可以阅读,AppCompat库目前不会渲染任何阴影.呼叫似乎在那里(例如ViewCompat.setElevation(View view, float elevation)),但它似乎没有做任何事情.

所以我想你现在需要求助于添加自己的阴影,至少在支持库实现阴影渲染之前.

查看Google IO 2014源代码,他们已实现如下:

有关此Reddit线程堆栈溢出的更多信息.