【问题标题】:No shadow by default on Toolbar?工具栏默认没有阴影?
【发布时间】:2014-12-21 21:38:33
【问题描述】:

我正在使用支持库 v21 中的新工具栏更新我的应用程序。我的问题是,如果我不设置“海拔”属性,工具栏不会投射任何阴影。这是正常行为还是我做错了什么?

我的代码是:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical">

   <android.support.v7.widget.Toolbar
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:id="@+id/my_awesome_toolbar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="?attr/colorPrimary"
       android:elevation="4dp"
       android:minHeight="?attr/actionBarSize"
       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
       app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

在我的 Activity - OnCreate 方法中:

    Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);

【问题讨论】:

  • 您是否在运行 Lollipop 的设备上看到此内容?
  • 在运行 Lollipop 的设备上由于海拔属性而显示阴影,但在 KitKat 或更旧版本上不显示。这就是文档所述的海拔属性的预期行为,但我期望在默认情况下没有海拔属性,阴影会像每个版本的操作栏一样投射。
  • 我在这里发布了一个可能的解决方案:stackoverflow.com/a/26759202/553905
  • 使用 /values 文件夹和 styles.xml 根据操作系统版本应用正确的影子代码(见下文)。

标签: android android-5.0-lollipop material-design android-toolbar


【解决方案1】:

我最终为工具栏设置了自己的阴影,认为它可能对寻找它的人有所帮助:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="top"
              android:orientation="vertical">

    <android.support.v7.widget.Toolbar android:id="@+id/toolbar"
                                       android:layout_width="match_parent"
                                       android:layout_height="wrap_content"
                                       android:background="@color/color_alizarin"
                                       android:titleTextAppearance="@color/White"
                                       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <FrameLayout android:layout_width="match_parent"
                 android:layout_height="match_parent">

        <!-- **** Place Your Content Here **** -->

        <View android:layout_width="match_parent"
              android:layout_height="5dp"
              android:background="@drawable/toolbar_dropshadow"/>

    </FrameLayout>

</LinearLayout>

@drawable/toolbar_dropshadow:

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

    <gradient android:startColor="@android:color/transparent"
              android:endColor="#88333333"
              android:angle="90"/>

</shape>

@color/color_alizarin

<color name="color_alizarin">#e74c3c</color>

【讨论】:

  • 如果您正在运行的设备 >= Lollipop,请不要忘记隐藏您的视图,否则您将得到两个阴影。
  • 这是错误的方法,因为您必须为 5.0 布局删除该视图。请改用 android:windowContentOverlay 或 android:foreground。
  • 来自谷歌关于设计Toolbar material design,你应该设置android:layout_height="4dp"作为阴影的高度,而不是5dp。实际上,高程与您在FrameLayout 上设置的阴影高度相同。
  • 我在使用这个解决方案时遇到了问题,因为我在你的示例中将我的活动布局膨胀到框架布局中,你能想出一种方法来解决这个问题吗?
  • 推荐使用 "android:endColor="#c7c7c7" 而不是 android:endColor="#88333333"
【解决方案2】:

Google 几周前发布了设计支持库,该库中有一个很好的解决方案。

build.gradle 中添加设计支持库作为依赖项:

compile 'com.android.support:design:22.2.0'

添加库提供的 AppBarLayout 作为 Toolbar 布局的包装器以生成投影。

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
       <android.support.v7.widget.Toolbar
           .../>
    </android.support.design.widget.AppBarLayout>

结果如下:

设计支持库还有很多其他技巧。

  1. http://inthecheesefactory.com/blog/android-design-support-library-codelab/en
  2. http://android-developers.blogspot.in/2015/05/android-design-support-library.html

AndroidX

同上,但有依赖关系:

implementation 'com.google.android.material:material:1.0.0'

com.google.android.material.appbar.AppBarLayout

【讨论】:

  • AppBarLayout 设置为Toolbar 的包装器不会为我设置任何阴影。请注意,我不使用导航抽屉。关于它为什么不起作用的任何想法?
  • @avb1994 不能肯定,我已经在没有导航抽屉的情况下对其进行了测试。您可以将其作为问题与布局文件一起发布吗?
  • 查看我的问题:stackoverflow.com/questions/31115531/… 感谢您的评论
  • 你不需要这两行 compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0',因为compile 'com.android.support:design:22.2.0' 取决于他们
  • 请注意这仅适用于棒棒糖及以上。它不会在棒棒糖之前工作,因为它只是在使用 ViewCompat.setElevation()。
【解决方案3】:

在 API 21 (Android Lollipop) 之前,您不能使用海拔属性。但是,您可以通过编程方式添加阴影,例如使用放置在工具栏下方的自定义视图。

@layout/工具栏

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

<View
    android:id="@+id/toolbar_shadow"
    android:layout_width="match_parent"
    android:layout_height="3dp"
    android:background="@drawable/toolbar_dropshadow" />

@drawable/toolbar_dropshadow

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient
        android:startColor="@android:color/transparent"
        android:endColor="#88333333"
        android:angle="90"/> </shape>

在您的活动布局中 &lt;include layout="@layout/toolbar" /&gt;

【讨论】:

  • 你能用完整的布局文件修复@layout/toolbar 示例吗?
  • 为什么@layout/toolbar 有两个根视图?你能提供完整的例子吗?
【解决方案4】:

使用 /values 文件夹根据操作系统版本应用正确的阴影样式。

对于 5.0 以下的设备,使用 /values/styles.xmlwindowContentOverlay 添加到您的活动主体:

<style name="MyViewArea">
    <item name="android:foreground">?android:windowContentOverlay</item>
</style>

<style name="MyToolbar">
    <item name="android:background">?attr/colorPrimary</item>
</style>

然后通过更改主题来添加您自己的自定义阴影:

<item name="android:windowContentOverlay">@drawable/bottom_shadow</item>

您可以在此处获取 Google 的 IO 应用影子资源:https://github.com/google/iosched/blob/master/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png

对于 5.0 及更高版本的设备,使用 /values-v21/styles.xml 通过自定义标题样式将 elevation 添加到您的工具栏:

<style name="MyViewArea">
</style>

<style name="MyToolbar">
    <item name="android:background">?attr/colorPrimary</item>
    <item name="android:elevation">4dp</item>
</style>

请注意,在第二种情况下,我必须创建一个空的 MyViewArea 样式,这样 windowContentOverlay 就不会出现。

[更新:更改了资源名称并添加了 Google 影子。]

【讨论】:

  • 我可以知道 MyBody 和 MyHeader 是什么吗?我应该在哪里应用它们?
  • 我更新了名称:MyHeader 现在是 MyToolbar,MyBody 是 MyViewArea。您可以像这样在 xml 布局中分配样式:style="@style/MyToolbar"。
  • MyViewArea 应用于什么?
  • 您的页面/正文/视图区域。
  • 我认为android:foreground 仅适用于 API 23 之前的 FrameLayout。
【解决方案5】:

这对我很有效:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/primary"
    card_view:cardElevation="4dp"
    card_view:cardCornerRadius="0dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary"
        android:minHeight="?attr/actionBarSize" />

</android.support.v7.widget.CardView>

【讨论】:

【解决方案6】:

如果您将ToolBar 设置为ActionBar,则只需调用:

getSupportActionBar().setElevation(YOUR_ELEVATION);

注意:这必须在setSupportActionBar(toolbar);之后调用

【讨论】:

  • 只是我,还是导航抽屉重置了工具栏的高度?我尝试将其设置为 0,并且它起作用了,但是当我拖动导航抽屉时,我又看到它有一个阴影......
  • setElevation() 仅针对 API-21+ 定义。
  • @Sebastian 支持操作栏提升也适用于以前的 API。
  • 在内部使用ViewCompat.setElevation(),因此仅适用于 API 21 及更高版本。
  • 在 API 21 下使用 android:windowContentOverlay 或 android:foreground。
【解决方案7】:

我加了

<android.support.v7.widget.Toolbar
...
android:translationZ="5dp"/>

在工具栏描述中,它对我有用。 使用 5.0+

【讨论】:

    【解决方案8】:

    我的问题是,如果我不设置“海拔”属性,工具栏不会投射任何阴影。这是正常行为还是我做错了什么?

    这是正常行为。另请参阅this post 末尾的常见问题解答。

    【讨论】:

      【解决方案9】:

      玩了几个小时,这对我有用。

      appBarLayoutToolbar 小部件中删除所有elevation 属性(包括styles.xml,如果您正在应用任何样式)。

      现在在活动中,在您的actionBar 上应用elvation

      Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
      setSupportActionBar(toolbar);
      getSupportActionBar().setElevation(3.0f);
      

      这应该可行。

      【讨论】:

      • 如果我想要 AppBarLayout 的高度,因为它可以折叠/展开?
      • setElevation 将参数作为像素。你必须适当地转换它,例如(int) (3.0 / Resources.getSystem().getDisplayMetrics().density)
      【解决方案10】:

      您只需要一个等于android:elevation 值的android:margin_bottom。不需要AppBarLayoutclipToPadding等。

      例子:

      <?xml version="1.0" encoding="utf-8"?>
      <androidx.appcompat.widget.Toolbar
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/toolbar"
          android:layout_width="match_parent"
          android:layout_height="?attr/actionBarSize"
          android:layout_marginBottom="4dp"
          android:background="@android:color/white"
          android:elevation="4dp">
      
          <androidx.constraintlayout.widget.ConstraintLayout
              android:layout_width="match_parent"
              android:layout_height="match_parent">
      
              <!--Inner layout goes here-->
      
          </androidx.constraintlayout.widget.ConstraintLayout>
      </androidx.appcompat.widget.Toolbar>
      

      【讨论】:

      • 没有任何效果,除了这个,正确且有意义
      【解决方案11】:

      您也可以使用RelativeLayout。这会稍微减少布局嵌套;)

      <RelativeLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      
          <include
              android:id="@+id/toolbar"
              layout="@layout/toolbar" />
      
          <FrameLayout
              android:id="@+id/container"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:layout_below="@id/toolbar" />
      
          <View
              android:layout_width="match_parent"
              android:layout_height="5dp"
              android:layout_below="@id/toolbar"
              android:background="@drawable/toolbar_shadow" />
      </RelativeLayout>
      

      【讨论】:

        【解决方案12】:

        在我的情况下,提升效果不佳,因为我没有为工具栏提供任何背景。尝试为工具栏设置背景颜色,然后设置高度,它会很好地工作。

        【讨论】:

          【解决方案13】:

          大多数解决方案在这里都可以正常工作。想展示另一个类似的替代方案:

          分级:

          implementation 'androidx.appcompat:appcompat:1.0.0-rc02'
          implementation 'com.google.android.material:material:1.0.0-rc02'
          implementation 'androidx.core:core-ktx:1.0.0-rc02'
          implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
          

          您的布局可以有一个工具栏视图,并在下面为它添加一个阴影,类似于此(当然需要修改):

          <LinearLayout
              xmlns:android="http://schemas.android.com/apk/res/android"
              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="?attr/actionBarSize"
                  android:background="?attr/colorPrimary"
                  android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                  app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                  app:titleTextAppearance="@style/Base.TextAppearance.Widget.AppCompat.Toolbar.Title"/>
          
              <include
                  layout="@layout/toolbar_action_bar_shadow"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"/>
          
          </LinearLayout>
          

          res/drawable-v21/toolbar_action_bar_shadow.xml

          <androidx.appcompat.widget.AppCompatImageView
              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"/>
          

          res/drawable/toolbar_action_bar_shadow.xml

          <FrameLayout
              xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent" android:layout_height="wrap_content"
              android:foreground="?android:windowContentOverlay" tools:ignore="UnusedAttribute"/>
          

          res/drawable/msl__action_bar_shadow.xml

          <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
              <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>
          

          styles.xml

          <resources>
              <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
                  <item name="colorPrimary">@color/colorPrimary</item>
                  <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
                  <item name="colorAccent">@color/colorAccent</item>
              </style>
          </resources>
          

          MainActivity.kt

          class MainActivity : AppCompatActivity() {
          
              override fun onCreate(savedInstanceState: Bundle?) {
                  super.onCreate(savedInstanceState)
                  setContentView(R.layout.activity_main)
                  setSupportActionBar(toolbar as Toolbar)
              }
          }
          

          完整示例 here,因为我注意到 IDE 有一个错误,即 foreground 属性太新,无法在此处使用。

          【讨论】:

            【解决方案14】:

            正确答案是添加
            android:backgroundTint="#ff00ff" 到工具栏 和 android:background="@android:color/white"

            如果您使用其他颜色而不是白色作为背景,它将消除阴影。 不错的谷歌!

            【讨论】:

              【解决方案15】:

              对于 5.0 + :您可以将 AppBarLayout 与 Toolbar 一起使用。 AppBarLayout 具有“海拔”属性。

               <android.support.design.widget.AppBarLayout
                      android:id="@+id/appbar"
                      android:layout_width="match_parent"
                      android:elevation="4dp"
                      android:layout_height="wrap_content"
                      android:orientation="vertical">
                      <include layout="@layout/toolbar" />
                  </android.support.design.widget.AppBarLayout>
              

              【讨论】:

              • 以前的版本呢?
              【解决方案16】:

              actionbar_background.xml

                  <item>
                      <shape>
                          <solid android:color="@color/black" />
                          <corners android:radius="2dp" />
                          <gradient
                              android:startColor="@color/black"
                              android:centerColor="@color/black"
                              android:endColor="@color/white"
                              android:angle="270" />
                      </shape>
                  </item>
              
                  <item android:bottom="3dp" >
                      <shape>
              
                          <solid android:color="#ffffff" />
                          <corners android:radius="1dp" />
                      </shape>
                  </item>
              </layer-list>
              

              添加到 actionbar_style 背景

              <style name="Theme.ActionBar" parent="style/Widget.AppCompat.Light.ActionBar.Solid">
                  <item name="background">@drawable/actionbar_background</item>
                  <item name="android:elevation">0dp</item>
                  <item name="android:windowContentOverlay">@null</item>
                  <item name="android:layout_marginBottom">5dp</item>
              

              name="displayOptions">useLogo|showHome|showTitle|showCustom

              添加到基本主题

              <style name="BaseTheme" parent="Theme.AppCompat.Light">
                 <item name="android:homeAsUpIndicator">@drawable/home_back</item>
                 <item name="actionBarStyle">@style/Theme.ActionBar</item>
              </style>
              

              【讨论】:

                【解决方案17】:

                我对阴影也有类似的问题。在我的例子中,阴影是由 AppBarLayout 的直接父级绘制的。如果父级的高度与 AppBarLayout 的高度相同,则无法绘制阴影。因此检查父布局的大小并可能重新制作布局可以解决问题。 https://www.reddit.com/r/androiddev/comments/6xddb0/having_a_toolbar_as_a_fragment_the_shadow/

                【讨论】:

                  【解决方案18】:

                  我发布这个是因为我花了好几个小时才找到它,所以我希望它可以帮助别人。

                  虽然我创建了一个简单的活动并按如下方式放置工具栏,但我遇到了阴影/高度没有显示的问题:

                   <androidx.appcompat.widget.Toolbar
                          android:id="@+id/mt_toolbar"
                          android:layout_width="match_parent"
                          android:layout_height="?attr/actionBarSize"
                          app:layout_collapseMode="pin"
                          android:background="@color/colorPrimaryDark"
                          android:elevation="12dp"/>
                  

                  原来在manifest 设置android:hardwareAccelerated="false" 导致了它!一旦我删除它,阴影就出现了

                  【讨论】:

                    【解决方案19】:
                    Just put  background
                     <androidx.appcompat.widget.Toolbar
                                    android:layout_width="match_parent"
                                    android:elevation="8dp"
                                    android:background="#fff"
                    
                                    android:layout_height="?android:attr/actionBarSize"></androidx.appcompat.widget.Toolbar>
                    

                    【讨论】:

                      【解决方案20】:

                      您需要将背景颜色和高度结合使用。

                      <com.google.android.material.appbar.MaterialToolbar
                           app:elevation="8dp"
                           android:elevation="8dp"
                           android:background="@color/white"/>
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2020-05-04
                        • 2016-10-27
                        • 2017-07-13
                        • 2019-12-23
                        • 2018-01-03
                        • 2023-04-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多