319

我有一个 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 和 TextViews 本身,而不是父布局。
  2. 为 ImageView 应用背景。
  3. 使用 TranslationZ 代替 Elevation。
4

22 回答 22

438

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

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

以下是我根据我所知道的给你的建议:

  1. 将顶层设置RelativeLayout为具有等于您在要显示阴影的相对布局上设置的边距的填充;
  2. 设置android:clipToPadding="false"相同RelativeLayout
  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"
    >
于 2014-12-17T04:07:21.103 回答
334

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

android:outlineProvider="bounds"

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

于 2015-07-07T14:46:30.457 回答
114

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

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

android:background="@android:color/white"
android:elevation="10dp"
于 2016-04-30T14:10:22.960 回答
54

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

安卓:硬件加速=“假”

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

于 2017-01-30T13:04:10.337 回答
44

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

android:outlineProvider="bounds"

如果您有背景视图,此行将对您有所帮助

android:outlineProvider="paddedBounds"
于 2018-07-11T12:34:41.003 回答
21

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

android:stateListAnimator="@null"

请参阅Android 5.0 android:elevation 适用于 View,但不适用于 Button?

于 2017-06-02T08:24:31.397 回答
13

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

例如,这不会有阴影:

<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>
于 2016-10-21T14:40:22.263 回答
7

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

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

    />
于 2016-09-22T14:54:29.453 回答
4

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

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

所以即使在设置之后

android:outlineProvider="bounds"

海拔不能正常工作,那么您可以尝试修改手机的颜色设置。

于 2016-06-29T09:19:02.260 回答
4

有时喜欢background="@color/***"background="#ff33**"不工作,我background_color用drawable替换,然后它工作

于 2017-05-03T10:10:32.390 回答
4

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

    android:hardwareAccelerated="true" 

这肯定会帮助你。

于 2019-04-01T07:00:01.367 回答
3

如果您想要透明背景并且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);
    }
}

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

transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));
于 2017-03-11T19:01:04.393 回答
3

给对我有用的布局提供一些背景颜色,例如:

    android:background="@color/catskill_white"
    android:layout_height="?attr/actionBarSize"
    android:elevation="@dimen/dimen_5dp"
于 2018-02-16T08:40:56.313 回答
1

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

于 2018-05-03T09:30:57.233 回答
1

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

于 2018-10-03T13:30:14.593 回答
1

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

于 2020-03-24T15:23:14.270 回答
1

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

android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:background="@drawable/card_view" //any drawable or color
android:elevation="4dp"
于 2021-09-16T08:31:19.097 回答
0

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

于 2016-01-29T17:46:38.477 回答
0

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

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" />
于 2018-04-17T09:21:32.237 回答
0

就我而言,这是由自定义父组件将渲染层类型设置为“软件”引起的:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

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

于 2019-01-18T21:42:33.017 回答
0

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

于 2020-07-26T17:46:35.190 回答
-2

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

于 2020-08-10T17:41:36.300 回答