Android"提升"没有出现阴影

时间:2014-12-15 04:29:16

标签: android material-design shadow android-elevation

我有一个ListView,每个列表项我想让它在它下面显示一个阴影。我正在使用Android Lollipop的新高程功能在View上设置一个我想要投射阴影的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>

但是,这是它如何显示列表项,没有阴影: enter image description here

我也试过以下无济于事:

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

21 个答案:

答案 0 :(得分:335)

我一直在玩Lollipop上的阴影,这就是我发现的:

  1. 由于某种原因,父母ViewGroup的界限似乎切断了孩子们的阴影;和
  2. 使用android:elevation设置的阴影被View的边界截断,而不是通过边距延伸的边界;
  3. 获取子视图以显示阴影的正确方法是在父级上设置填充并在该父级上设置android:clipToPadding="false"
  4. 根据我所知,这是我给你的建议:

    1. 将您的顶级RelativeLayout设置为等于您在要显示阴影的相对布局上设置的边距;
    2. android:clipToPadding="false";
    3. 上设置RelativeLayout
    4. RelativeLayout中删除也具有高程设置的边距;
    5. [编辑]您可能还需要在需要提升的子布局上设置不透明的背景颜色。
    6. 在一天结束时,您的顶级相对布局应如下所示:

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

答案 1 :(得分:255)

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

android:outlineProvider="bounds"

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

答案 2 :(得分:83)

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

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

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

答案 3 :(得分:37)

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

<强> 机器人:硬件加速= “假”

我尝试了所有建议的东西,但它只对我有效,当我删除该行时,我有这条线的原因是因为我的应用程序使用了许多位图图像而且它们导致应用程序崩溃。

答案 4 :(得分:16)

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

android:stateListAnimator="@null"

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

答案 5 :(得分:14)

如果您没有背景视图,此行将为您提供帮助

android:outlineProvider="bounds"

如果您有背景视图,此行将为您提供帮助

android:outlineProvider="paddedBounds"

答案 6 :(得分:11)

呃,花了一个小时试图解决这个问题。在我的情况下,我有一个背景设置,但它被设置为一种颜色。这还不够,您需要将视图的背景设置为drawable。

e.g。 这不会有影子:

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

编辑: 还发现如果您使用选择器作为背景,如果您没有角落设置,则阴影将不会显示在预览窗口中,但它将显示在设备上< / p>

e.g。这在预览中没有阴影:

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

答案 7 :(得分:6)

添加背景色帮助了我。

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

    />

答案 8 :(得分: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);
    }
}

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

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

答案 9 :(得分:3)

有时候background="@color/***"background="#ff33**"不起作用,我会将background_color替换为drawable,然后才能正常工作

答案 10 :(得分:2)

为我的布局提供一些背景颜色 像:

onViewHolderBind()

答案 11 :(得分:1)

添加到已接受的答案中,还有一个原因是由于高程可能无法按预期工作。

  

如果手机上的蓝光滤镜功能开启

当我的设备中的高度完全失真且无法忍受时,我遇到了这个问题。但预览中的高度很好。关闭手机上的Bluelight过滤器解决了这个问题。

所以即使在设置

之后
android:outlineProvider="bounds"

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

答案 12 :(得分:1)

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

答案 13 :(得分:1)

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

    android:hardwareAccelerated="true" 

这肯定会对您有所帮助。

答案 14 :(得分:1)

还要检查您是否在该视图上不更改Alpha。当我在某些视图中使用高程更改Alpha时,我正在调查问题。 更改alpha并将其更改回1f时,它们只是放宽了海拔。

答案 15 :(得分:0)

我认为您的问题源于您已将高程元素应用于填充其父级的相对布局。其父级会在其自己的绘图画布中剪切所有子视图(并且是处理子级阴影的视图)。您可以通过将提升属性应用于视图xml中最顶层的{{1}}(根标记)来解决此问题。

答案 16 :(得分: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" />

答案 17 :(得分:0)

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

答案 18 :(得分:0)

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

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

删除这一行就可以了。或者,当然,您首先需要评估为什么要这样做。就我而言,这是为了支持Honeycomb,它远远落后于我项目的当前最低SDK。

答案 19 :(得分:0)

在顶部相对布局中设置android:clipToPadding =“ false”已解决了问题。

答案 20 :(得分:-1)

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