安卓视图阴影

119

我搜索过,但找不到合适的方法实现以下视图的阴影效果:

图片描述

图片描述

说实话,我不知道第二个是不是通过应用阴影效果来完成的。有什么想法吗?


1
你是指这个吗?https://dev59.com/g2855IYBdhLWcg3wViot(查看最高票答案,而不是标记的答案) - Luke Vo
1
@DatVM,谢谢,这似乎可以解决问题,但我在想也许Android SDK中有内置工具。例如,通过添加几行代码为线性布局添加阴影效果 :P - longwalker
类似问题 - https://dev59.com/sK_la4cB1Zd3GeqPq06k - 如何给矢量图添加阴影。 - Mayank Kumar Chaudhari
13个回答

167

我知道这个问题已经有答案了,但我想让你知道我在Android Studio上找到了一个非常类似于你在问题中的图片的drawable: 看看这个:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

它看起来像这样:

在此输入图片描述

希望这会有帮助。

编辑

上面的选项适用于旧版本的Android Studio,因此您可能找不到它。对于更新的版本:

android:background="@android:drawable/dialog_holo_light_frame"
此外,如果您想要自己的定制形状,我建议使用绘图软件如Photoshop进行绘制。

此处是图片描述

不要忘记将其保存为.9.png文件(例如:my_background.9.png)。
阅读文档:Draw 9-patch

编辑2

一个更好的且较少费力的解决方案是使用CardView并设置app:cardPreventCornerOverlap="false"以防止视图重叠边框:
<android.support.v7.widget.CardView
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="2dp"
    app:cardElevation="2dp"
    app:cardPreventCornerOverlap="false"
    app:contentPadding="0dp">

    <!-- your layout stuff here -->

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

还要确保在build.gradle中包含了最新的版本,当前版本为

compile 'com.android.support:cardview-v7:26.0.0'

谢谢,实际上看起来非常相似。我也发现了 Android 的“Google 卡片布局”,它们非常酷! - longwalker
7
很棒。只是提醒未来的观众,这在 /<sdk-path>/extras/android/support 中。 - theblang
2
使用cardView怎么样? - Alex Chengalan

105

我正在使用Android Studio 0.8.6,但我找不到:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

所以我找到了这个替代品:

android:background="@android:drawable/dialog_holo_light_frame"

它看起来像这样:

在此输入图像描述


3
但是我们不能为它添加圆角半径吗? - Fay007

41

使用@android:drawable/dialog_holo_light_frame作为背景可以产生阴影,但是你不能更改背景颜色和边框样式,因此最好利用它的阴影效果,同时仍然可以通过图层列表设置背景。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--the shadow comes from here-->
    <item
        android:bottom="0dp"
        android:drawable="@android:drawable/dialog_holo_light_frame"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp">

    </item>

    <item
        android:bottom="0dp"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp">
        <!--whatever you want in the background, here i preferred solid white -->
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />

        </shape>
    </item>
</layer-list>

将其保存在drawable文件夹下,名称为shadow.xml

要将其分配给视图,在xml布局文件中设置其背景

android:background="@drawable/shadow"

你检查过它是否能正常工作了吗?第二个<item>没有任何作用。我无法将其更改为透明或圆角。 - zeeshan
2
在我尝试的所有方法中,这是唯一有效的,谢谢。 - Shyam Sunder
1
绝妙的解决方案 - user1974368

36

在res/drawable文件夹中创建card_background.xml文件,其代码如下:

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

<item>
    <shape android:shape="rectangle">
        <solid android:color="#BDBDBD"/>
        <corners android:radius="5dp"/>
    </shape>
</item>

<item
    android:left="0dp"
    android:right="0dp"
    android:top="0dp"
    android:bottom="2dp">
    <shape android:shape="rectangle">
        <solid android:color="#ffffff"/>
        <corners android:radius="5dp"/>
    </shape>
</item>
</layer-list>

然后将以下代码添加到您想要使用卡片布局的元素中

android:background="@drawable/card_background"
以下代码定义了卡片阴影的颜色。
<solid android:color="#BDBDBD"/>

14
这实际上不是阴影,因为它不会消失。更像是在两侧的边界。 - ban-geoengineering
这不是一个阴影。 - ShadeToD

32

1
目前最佳答案也适用于Android 13。 - Arsalan Fakhar Siddiqui
以上的解决方案都对我没用,但你的有用!而且还是所有方案中最简洁的一个!谢谢! - undefined

25

CardView 可以在 Android 5+ 上为你的视图提供真实的阴影效果,并且它有支持库。只需用它包装你的视图,就完成了。

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

这需要下一个依赖项。

dependencies {
    ...
    compile 'com.android.support:cardview-v7:21.0.+'
}

1
这是唯一正确的答案,因为只有CardView在兼容模式下具有不同高度的变化阴影级别。 - Jarett Millard
我建议使用MaterialCardView,因为它更清晰并且具有更多的功能。 - HF_

12
这可能有点晚了,但对于那些仍在寻找答案的人,我在GitHub上找到了一个项目,这是唯一真正符合我的需求的项目。 android-materialshadowninepatch 只需将此行添加到您的build.gradle依赖项中。
compile 'com.h6ah4i.android.materialshadowninepatch:materialshadowninepatch:0.6.3'

为创作者欢呼,点赞!愉快的编码


嘿@ralphgabb,这对您仍然有效还是您有更好的解决方案适用于Lollipop版本之前的设备? - Swapnil
@Swapnil不确定AndroidX现在是否支持此功能,但我不再支持棉花糖之前的设备。 - ralphgabb

9

我知道这种方法很粗糙,
但如果你想支持v21以下版本,这是我的成果。

rectangle_with_10dp_radius_white_bg_and_shadow.xml

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

    <!-- Shadow layers -->
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_1" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_2" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_3" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_4" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_5" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_6" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_7" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_8" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_9" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_10" />
        </shape>
    </item>

    <!-- Background layer -->
    <item>
        <shape>
            <solid android:color="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>

</layer-list>

rectangle_with_10dp_radius_white_bg_and_shadow.xml(v21)

这是一个具有10dp圆角、白色背景和阴影的矩形。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/white" />
    <corners android:radius="10dp" />
</shape>

view_incoming.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="@drawable/rectangle_with_10dp_radius_white_bg_and_shadow"
    android:elevation="7dp"
    android:gravity="center"
    android:minWidth="240dp"
    android:minHeight="240dp"
    android:orientation="horizontal"
    android:padding="16dp"
    tools:targetApi="lollipop">

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="Hello World !" />

</LinearLayout>

以下是结果:

在v21版本以下(这是您使用xml创建的版本)输入图像描述

在v21版本以上(真正的高程渲染)输入图像描述

  • 一个显著的区别是它会占用视图中的内部空间,因此您的实际内容区域可能比>= lollipop设备更小。

最好设置真实的颜色值以查看结果。 - CoolMind

7
如果你需要正确应用阴影,则需要遵循以下步骤。
考虑这个视图,它使用背景可绘制对象定义:
<TextView
    android:id="@+id/myview"
    ...
    android:elevation="2dp"
    android:background="@drawable/myrect" />

背景可绘制对象被定义为带有圆角的矩形:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#42000000" />
    <corners android:radius="5dp" />
</shape>

这是应用阴影的推荐方法,请查看此链接:https://developer.android.com/training/material/shadows-clipping.html#Shadows

6
创建这样的背景drawable以显示圆角阴影。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Drop Shadow Stack -->
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#00CCCCCC" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#10CCCCCC" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#20d5d5d5" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="6dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#30cbcbcb" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#50bababa" />
        </shape>
    </item>

    <!-- Background -->
    <item>
        <shape>
            <solid android:color="@color/gray_100" />
            <corners android:radius="4dp" />
        </shape>
    </item>
</layer-list>

请为您提供的代码添加描述。 - Mangaldeep Pannu
1
非常好的XML解决方案。 - Bruno Bieri
可能这是一个不错的解决方案,但在白色背景上,如果设置了细边框,它看起来像一个浅灰色矩形。 - CoolMind

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