【问题标题】:Android "elevation" not showing a shadowAndroid“海拔”不显示阴影
【发布时间】:2015-02-13 03:43:20
【问题描述】:

我有一个 ListView,对于每个列表项,我希望它在其下方显示一个阴影。我正在使用 Android Lollipop 的新高度功能在要投射阴影的视图上设置 Z,并且已经使用 ActionBar(技术上是 Lollipop 中的工具栏)有效地执行此操作。我正在使用 Lollipop 的海拔,但由于某种原因,它没有在列表项下显示阴影。下面是如何设置每个列表项的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    >

    <RelativeLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:elevation="30dp"
        >

        <ImageView
            android:id="@+id/documentImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop" />

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/alphared"
            android:layout_alignParentBottom="true" >

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="light"
                android:paddingLeft="16dp"
                android:paddingTop="8dp"
                android:paddingBottom="4dp"
                android:singleLine="true"
                android:text="New Document"
                android:textSize="27sp"/>

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentPageCount"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="italic"
                android:paddingLeft="16dp"
                android:layout_marginBottom="16dp"
                android:text="1 page"
                android:textSize="20sp"/>

        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

但是,这里是它显示列表项的方式,没有阴影:

我也尝试了以下方法,但无济于事:

  1. 将高程设置为 ImageView 和 TextView 本身,而不是父布局。
  2. 为 ImageView 应用了背景。
  3. 使用 TranslationZ 代替 Elevation。

【问题讨论】:

标签: android material-design shadow android-elevation


【解决方案1】:

我在 Lollipop 上玩了一段时间的阴影,这就是我发现的:

  1. 似乎父ViewGroup 的边界由于某种原因切断了其子的影子;和
  2. android:elevation 设置的阴影被View 的边界截断,而不是通过边距延伸的边界;
  3. 让子视图显示阴影的正确方法是在父视图上设置填充并在该父视图上设置 android:clipToPadding="false"

根据我的了解,以下是我对您的建议:

  1. 将您的顶级RelativeLayout 设置为具有等于您在要显示阴影的相对布局上设置的边距;
  2. 在同一个RelativeLayout上设置android:clipToPadding="false"
  3. 从同样设置了高程的RelativeLayout 中删除边距;
  4. [编辑] 您可能还需要在需要提升的子布局上设置不透明的背景颜色。

最终,您的顶级相对布局应如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    android:paddingLeft="40dp"
    android:paddingRight="40dp"
    android:paddingTop="20dp"
    android:paddingBottom="20dp"
    android:clipToPadding="false"
    >

内部相对布局应该是这样的:

<RelativeLayout
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:background="[some non-transparent color]"
    android:elevation="30dp"
    >

【讨论】:

  • 谢谢!我还发现 android:clipChildren="false" 在应用于父相对布局时很有用。
  • 很高兴帮助@blaffie!
  • Google 产生如此粗制滥造的代码实在是太烦人了。多年来,我们将不得不考虑这些框架错误。
  • Google 只说(唉):“阴影由提升视图的父级绘制,因此受到标准视图裁剪,默认由父级裁剪。” .
  • 在我的例子中是透明色。好吧,透明的东西不会投下阴影……哈哈
【解决方案2】:

如果你有一个没有背景的视图,这条线会帮助你

android:outlineProvider="bounds"

默认情况下阴影是由视图的背景决定的,所以如果没有背景,也不会有阴影。

【讨论】:

  • 多么奇怪的事情,预览显示高度,但真实设备没有。谢谢,这个解决了这个问题。
  • 适用于 API 级别 21 及更高级别
  • 这种方法对我有用,但在应用于 textview 时,两侧会出现对角线边框。将背景设置为一种颜色(与父背景颜色相同)效果更好。
  • 如果您的背景是自定义的并且没有&lt;solid&gt;,这也适用。
  • 这个可以反向使用。当您想要具有高度的非透明背景并且不想要阴影时。只需将其设置为none。谢谢!
【解决方案3】:

显然,您不能只在视图上设置高程并让它出现。您还需要指定背景。

添加到我的LinearLayout中的以下几行终于显示了阴影:

android:background="@android:color/white"
android:elevation="10dp"

【讨论】:

  • 这是出乎意料的。我已经用 src 设置了 ImageView 并正在寻找解决方案。谢谢。
【解决方案4】:

您应该注意的另一件事是,如果清单中有此行,阴影将不会显示:

android:hardwareAccelerated="false"

我尝试了所有建议的东西,但它只在我删除该行时才对我有用,我有该行的原因是因为我的应用程序与许多位图图像一起使用并且它们导致应用程序崩溃。

【讨论】:

  • 这并不能解决问题,如果您需要该标志存在。
  • 谢谢!!我花了一天时间尝试提升 AppBar 并在检查清单中是否有此活动标志时发现了问题
  • 我尝试了所有可能的解决方案,但没有一个对我有用。这个解决方案奏效了。谢谢。此解决方案还需要android:clipToPadding="false"
【解决方案5】:

如果你有一个没有背景的视图,这条线会帮助你

android:outlineProvider="bounds"

如果你有背景视图,这条线会帮助你

android:outlineProvider="paddedBounds"

【讨论】:

  • 这个解决方案是唯一适合我的。谢谢
  • 此方法有效,除非您的视图背景上有半径,在这种情况下,阴影将显示为矩形,但 paddedBounds 确实适用于具有背景的视图。
  • android:outlineProvider="paddedBounds" 这条线对我有用。我设置了 Selector Drawable。
  • 当我使用它时,阴影完全绘制在视图内部而不是外部,这不是我想要的。
【解决方案6】:

如果要为按钮元素添加高程,则需要添加以下行:

android:stateListAnimator="@null"

Android 5.0 android:elevation Works for View, but not Button?

【讨论】:

  • 这应该是顶级的
【解决方案7】:

呃,刚刚花了一个小时试图弄清楚这一点。就我而言,我有一个背景集,但是它被设置为一种颜色。这还不够,您需要将视图的背景设置为可绘制对象。

例如 这不会有阴影:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@color/ight_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

但这会

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@drawable/selector_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

编辑: 还发现如果您使用选择器作为背景,如果您没有设置角,那么阴影将不会出现在 预览窗口中,但会出现在设备上

例如这在预览中没有阴影:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

但确实如此:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <corners android:radius="1dp" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

【讨论】:

  • 在 RecyclerView 项目中对我来说与您的第一点完全相反......令人惊讶的是,经过 5 年的专业 Android 开发后,我仍然发现我必须与这些 API 作斗争的案例:(
【解决方案8】:

添加背景颜色对我有帮助。

<CalendarView
    android:layout_width="match_parent"
    android:id="@+id/calendarView"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:layout_height="wrap_content"
    android:elevation="5dp"

    android:background="@color/windowBackground"

    />

【讨论】:

    【解决方案9】:

    有时像background="@color/***"background="#ff33**" 不起作用,我将background_color 替换为drawable,然后它起作用了

    【讨论】:

      【解决方案10】:

      如果仍然没有显示海拔,请尝试

          android:hardwareAccelerated="true" 
      

      这肯定会对你有所帮助。

      【讨论】:

      • 这为我解决了问题。我曾假设 TRUE 是默认设置,但显然不是,至少在我的情况下。
      【解决方案11】:

      除了已接受的答案之外,还有一个原因是,如果手机上的蓝光过滤器功能开启,提升可能无法按预期工作。

      当海拔在我的设备中完全扭曲且难以忍受时,我遇到了这个问题。但是预览中的海拔很好。关闭手机上的蓝光过滤器解决了这个问题。

      所以即使在设置之后

      android:outlineProvider="bounds"
      

      海拔不正常,你可以尝试修改手机的颜色设置。

      【讨论】:

      • 我设置了但它显示方形阴影..
      【解决方案12】:

      如果你想要透明背景而android:outlineProvider="bounds" 不适合你,你可以创建自定义 ViewOutlineProvider:

      class TransparentOutlineProvider extends ViewOutlineProvider {
      
          @Override
          public void getOutline(View view, Outline outline) {
              ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
              Drawable background = view.getBackground();
              float outlineAlpha = background == null ? 0f : background.getAlpha()/255f;
              outline.setAlpha(outlineAlpha);
          }
      }
      

      并将此提供程序设置为您的透明视图:

      transparentView.setOutlineProvider(new TransparentOutlineProvider());
      

      来源: https://code.google.com/p/android/issues/detail?id=78248#c13

      [编辑] Drawable.getAlpha() 的文档说它特定于 Drawable 如何威胁 alpha。它可能总是返回 255。 在这种情况下,您可以手动提供 alpha:

      class TransparentOutlineProvider extends ViewOutlineProvider {
      
          private float mAlpha;
      
          public TransparentOutlineProvider(float alpha) {
              mAlpha = alpha;
          }
      
          @Override
          public void getOutline(View view, Outline outline) {
              ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
              outline.setAlpha(mAlpha);
          }
      }
      

      如果您的视图背景是 StateListDrawable,默认颜色为 #DDFF0000,alpha DDx0/FFx0 == 0.86

      transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));
      

      【讨论】:

        【解决方案13】:

        为适合我的布局提供一些背景颜色 喜欢:

            android:background="@color/catskill_white"
            android:layout_height="?attr/actionBarSize"
            android:elevation="@dimen/dimen_5dp"
        

        【讨论】:

          【解决方案14】:

          我在父布局上设置了clipChildren="false" 运气不错。

          【讨论】:

            【解决方案15】:

            我花了一些时间研究它,终于意识到当背景很暗时,阴影是不可见的

            【讨论】:

              【解决方案16】:

              还要检查您是否没有更改该视图的 alpha。当我在某些视图上更改 alpha 时,我正在调查问题。 当 alpha 更改并改回 1f 时,它们只会降低高度。

              【讨论】:

                【解决方案17】:

                对我来说,设置高度、背景和边距就像一种魅力。

                android:layout_marginStart="5dp"
                android:layout_marginEnd="5dp"
                android:background="@drawable/card_view" //any drawable or color
                android:elevation="4dp"
                

                【讨论】:

                  【解决方案18】:

                  我相信您的问题源于您已将高程元素应用于填充其父级的相对布局这一事实。它的父级在其自己的绘图画布中剪辑所有子视图(并且是处理子阴影的视图)。您可以通过将海拔属性应用到视图 xml(根标记)中最顶部的 RelativeLayout 来解决此问题。

                  【讨论】:

                    【解决方案19】:

                    就我而言,字体是问题所在。

                    1) 如果没有fontFamily,我需要将android:background 设置为某个值。

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="44dp"
                        android:background="@android:color/white"
                        android:elevation="3dp"
                        android:gravity="center"
                        android:text="@string/fr_etalons_your_tickets"
                        android:textAllCaps="true"
                        android:textColor="@color/blue_4" />
                    

                    2) 使用fontFamily 我必须添加android:outlineProvider="bounds" 设置:

                    <TextView
                        android:fontFamily="@font/gilroy_bold"
                        android:layout_width="match_parent"
                        android:layout_height="44dp"
                        android:background="@android:color/white"
                        android:elevation="3dp"
                        android:gravity="center"
                        android:outlineProvider="bounds"
                        android:text="@string/fr_etalons_your_tickets"
                        android:textAllCaps="true"
                        android:textColor="@color/blue_4" />
                    

                    【讨论】:

                      【解决方案20】:

                      在我的例子中,这是由自定义父组件将渲染层类型设置为“软件”引起的:

                      setLayerType(View.LAYER_TYPE_SOFTWARE, null);
                      

                      删除这行就行了。或者当然,您首先需要评估为什么会出现这种情况。就我而言,它是为了支持 Honeycomb,这远远落后于我项目的当前最低 SDK。

                      【讨论】:

                        【解决方案21】:

                        在顶部相对布局中设置 android:clipToPadding="false" 解决了这个问题。

                        【讨论】:

                          【解决方案22】:

                          为布局或视图设置背景颜色

                          【讨论】:

                            猜你喜欢
                            • 2015-08-22
                            • 2015-02-14
                            • 2016-11-11
                            • 1970-01-01
                            • 2016-02-03
                            • 2017-10-15
                            • 2021-05-17
                            • 2017-07-13
                            • 2018-07-09
                            相关资源
                            最近更新 更多