LinearLayout上的Elevation无效

52

在寻找解决方案之后,我没有找到任何解决我的问题的方法。

我的某些高度会在我的应用程序的大部分区域产生阴影。
但是在一个特定的地方,我无法使它工作。
(就是我在下面图片上放箭头的那个地方)

进入图像描述

工具栏下面的白色区域是一个显示LinearLayoutFragment

布局:

<LinearLayout
    android:id="@+id/panelAddress"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/button_flat_white"
    android:elevation="10dp"
    android:orientation="vertical"
    android:padding="20dp"
    >  
//some content
</LinearLayout>

片段的父级:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawerLayout"
    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:orientation="vertical"
    >

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

        <include
            android:id="@+id/custom_toolbar"
            layout="@layout/toolbar"/>

        <RelativeLayout
            android:id="@+id/mapLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <fragment
                android:id="@+id/map"
                class="com.google.android.gms.maps.SupportMapFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

            <FrameLayout
                android:id="@+id/fragment_container_top"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                />

            <FrameLayout
                android:id="@+id/fragment_container_bottom"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"/>

        </RelativeLayout>

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

你知道为什么我获取不到海拔高度吗?


将LinearLayout的背景颜色设置为红色,以便了解它的实际面积。它可能会延伸到整个片段。 - SilverCorvus
@CurlyCorvus,它需要正确的位置。 - agonist_
你在你的碎片中尝试过android:outlineProvider="bounds"了吗? - Jorge Casariego
8个回答

78

这里所描述的,要绘制阴影需要满足以下几个条件:

  • 在父视图组中预留空间以绘制阴影。正如bleeding182所提到的,填充(padding)可能导致阴影被截断:

    (不要使用填充。Framelayout上的填充也会切掉阴影)

    然而,你可以通过在父视图中添加android:clipToPadding="false"来解决这个问题。

  • 要投射阴影,突起的视图需要有一个背景。我无法确定在你的情况下@drawable/button_flat_white是否存在此问题。

为了解决你的问题,你应该像这样修改你的FrameLayout:

<FrameLayout
        android:id="@+id/fragment_container_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"

        android:clipToPadding="false"
        android:paddingBottom="10dp"/>

为了检查@drawable/button_flat_white是否会造成任何问题,请尝试暂时将LinearLayout的背景更改为简单颜色:

<LinearLayout
    android:id="@+id/panelAddress"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:elevation="10dp"
    android:orientation="vertical"
    android:padding="20dp"

    android:background="#fff">  
//some content
</LinearLayout>

24

只需将CardView作为您的LinearLayout的父级,就可以实现阴影效果。

<android.support.v7.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    card_view:cardUseCompatPadding="true"
    card_view:cardElevation="4dp"
    card_view:cardCornerRadius="3dp">

       <LinearLayout
              android:id="@+id/panelAddress"
              xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@drawable/button_flat_white"
              android:orientation="vertical"
              android:padding="20dp">  

            //some content
      </LinearLayout>
 </android.support.v7.widget.CardView>

1
我认为这是最好的解决方案。其他不使用CardViews的解决方案总是会出现一些问题。 - RominaV
如何处理早期Lollipop版本的边缘空白? - TheRealChx101
@TheRealChx101 我认为你需要为Android 5.0以下和5.0以上分别创建不同的布局。 - ch3tanz

10
如果高度不起作用,则可以通过将参考设置为LinearLayout上的背景来创建XML: shadowfile.xml
    <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#18000000" />
            <corners android:radius="8dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#05000000" />
            <corners android:radius="7dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#10000000" />
            <corners android:radius="6dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#15000000" />
            <corners android:radius="5dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
            <solid android:color="#20000000" />
            <corners android:radius="4dp" />
        </shape>
    </item>

    <!-- Background -->
    <item>
        <shape>
            <solid android:color="#FFFFFF" />
            <corners android:radius="0dp" />
        </shape>
    </item>
</layer-list>

就像这样添加:

<LinearLayout
        android:id="@+id/profileDetails"
        android:layout_width="match_parent"
        android:layout_height="125dp"
        android:background="@drawable/shadowfile"
        android:padding="15dp"
        android:layout_below="@id/toolbar_title"
        android:layout_marginTop="20dp">

输出:

在这里输入图片描述


(Note: 这是一张图片,无法翻译)

2
这是一个绘图问题。
投影阴影被绘制在实际视图范围之外,因此如果父布局没有为视图提供足够的空间,则会被裁剪。
由于片段的父级(线性布局)具有相同的大小,因此阴影被裁剪。在LinearLayout底部添加一些边距。
如果这样做没有帮助,请尝试用稍微有点底部边距的FrameLayout包装布局(不要使用填充。Framelayout上的填充也会切断阴影)。
1-2dp应该就可以了。

啊,谢谢你。经过多次尝试,只有这个对我有效。 - Alexander

0
  • 如果你在manifest中设置了android:hardwareAccelerated="false",那么阴影将不会显示。

  • 如果上面的问题已经解决,请在你的布局中尝试android:clipToPadding="false"android:outlineProvider="bounds"


0

我使用了paddingRightpaddingBottom(用于在布局底部和右侧显示阴影),然后它对我起作用了,否则可绘制的阴影将无法正常工作。

如果你遇到同样的问题,可以尝试这样做。


-1

希望能对你有所帮助,只需在第二个布局中添加"marginTop"。

<LinearLayout
    android:id="@+id/linearLayout1"
    android:layout_width="match_parent"
    android:layout_height="90dp"
    android:orientation="vertical"
    android:elevation="5dp"
     />

<LinearLayout
    android:id="@+id/linearLayout2"
    android:layout_width="match_parent"
    android:layout_height="90dp"
    android:orientation="vertical"
    android:padding="5dp"
    android:layout_marginTop="3dp"
    />

-5
请在清单文件中启用硬件加速选项,
<application
  ...
  android:hardwareAccelerated="true">

1
那不是问题。就像我说的,我已经有很多海拔高度正常的地方了。但这并没有解决问题 =/ - agonist_
启用hardwareAccelerated的原理是什么? - rakesh kashyap
2
实际上,如果您在清单文件中将hardwareAccelerated=false,则任何类似阴影或透明的东西都不起作用,这个答案是有道理的。默认情况下是正确的,但有些人在创建选项卡时会使用它。所以我赞同这个答案并感谢您。 - tiwarinitin94

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接