Android LinearLayout:在LinearLayout周围添加带有阴影的边框

171

我想要创建一个和这个LinearLayout示例一样的边框:

enter image description here

在这个示例中,我们可以看到LinearLayout的边框不是完全相同的。 我如何使用XML可绘制文件来创建这个效果?

目前,我只能创建一个简单的四周都有边框的LinearLayout, 就像这样:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <corners
      android:radius="1dp"
      android:topRightRadius="0dp"
      android:bottomRightRadius="0dp"
      android:bottomLeftRadius="0dp" />
  <stroke
      android:width="1dp"
      android:color="#E3E3E1" />

  <solid android:color="@color/blanc" />

</shape>

1
你可以使用 background 属性来实现这个功能...创建一个形状为矩形、颜色和阴影效果的 XML 文件,并将其设置为线性布局的背景。 - Pragnesh Ghoda シ
请使用虚线来实现灰色边框和填充效果。 - Pragnesh Ghoda シ
我认为,它有两个布局 XML 文件,一个是线性布局,另一个是相对布局,内部带填充。 - Giru Bhai
1
另一种方法是使用9 patch图像作为布局的背景。这将允许实现非常平滑、渐变的阴影效果(在我看来更加逼真)。 - Phantômaxx
请查看我在这里对同一问题的回答:https://dev59.com/zWAf5IYBdhLWcg3wOQcL#34274763 - Ethan
显示剩余2条评论
14个回答

296

尝试这个,如匿名贡献者在Android开发人员技巧和窍门中所示:

<?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="#CABBBBBB"/>
            <corners android:radius="2dp" />
        </shape>
    </item>

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

@Hariharan 非常感谢!我尝试了你的代码,看起来还不错。但是,还有一件事情需要做,我该如何在LinearLayout的左侧和右侧添加一个细边框(1dp)?(就像示例中那样) - wawanopoulos
2
@wawanopoulos 只需在Hariharan的答案中将“0dp”替换为“1dp”。 - Phantômaxx
您可以将 #EAEAEA 颜色添加到父布局中,这样它就会像问题图片一样。 - Samad
4
我建议您可以在 <shape> 中使用 <gradient> 来增强边框效果,如果您的UI确实需要这种效果而不仅仅是纯色边框。请注意不要改变原意。 - patrickjason91
如果您的内部布局使用match_parent,请给内部布局添加1的边距。 - Shaktisinh Jadeja
非常感谢分享这个。将边框调整为1dp,将填充调整为1dp,将半径调整为5dp,以创建卡片视图效果。 - Merlin Jeyakumar

93

这就是为什么CardView存在的原因。CardView | Android Developers
它只是一个支持在早期版本设备上进行高度抬升(elevation)的FrameLayout。

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

    <!-- put whatever you want -->

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

使用此功能需要在 build.gradle 文件中添加依赖项:

compile 'com.android.support:cardview-v7:23.+'

如何更改阴影颜色。 - Aditay Kaushal
阴影非常弱。https://dev59.com/Aanka4cB1Zd3GeqPO36R - user924
1
在安装有4.4.4(或类似版本)的设备中出现非常奇怪的行为。CardView 添加了巨大的页边距,使界面非常丑陋。 - Morteza Rastgoo
这应该是被接受的答案。不过有一个小更新。你应该使用androidx中的-> androidx.cardview.widget.CardView - bogdan

64

我使用9个图形块的图片,得到最好的外观效果。

你可以通过以下编辑器轻松创建单个9个图形块的图片: http://inloop.github.io/shadow4android/

举个例子:

9个图形块的图片:

The 9 patch graphic:

结果:

enter image description here

源代码:

<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="@drawable/my_nine_patch"

1
如何隐藏黑线?请帮忙。 - Isaac Darlong
1
@Isaac 将图像保存为 my_nine_patch.9.png(.9.png 是九宫格图像) - arun

42

好的,我知道现在已经太晚了。但是我有相同的需求,我是这样解决的:

1.首先在“drawable”文件夹中创建一个xml文件(例如:border_shadow.xml),并将以下代码复制到其中。

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

<item>
    <shape>
        <!-- set the shadow color here -->
        <stroke
            android:width="2dp"
            android:color="#7000" />

        <!-- setting the thickness of shadow (positive value will give shadow on that side) -->

        <padding
            android:bottom="2dp"
            android:left="2dp"
            android:right="-1dp"
            android:top="-1dp" />

        <corners android:radius="3dp" />
    </shape>
</item>

<!-- Background -->

<item>
    <shape>
        <solid android:color="#fff" />
        <corners android:radius="3dp" />
    </shape>
</item>

</layer-list>

2.现在在您想要添加阴影的布局上(例如:LinearLayout)将以下内容添加到android:background中。

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dip"
    android:background="@drawable/border_shadow"
    android:orientation="vertical">

而且那对我有效。


28

这很简单:

创建一个带有渐变的可绘制文件,如下所示:

对于视图下方的阴影,请使用below_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">   
<gradient
    android:startColor="#20000000"
    android:endColor="@android:color/transparent"
    android:angle="270" >
</gradient>
</shape>

用于视图上方的阴影,above_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">   
<gradient
    android:startColor="#20000000"
    android:endColor="@android:color/transparent"
    android:angle="90" >
</gradient>
</shape>

针对右侧和左侧阴影,只需改变渐变的角度即可 :)


我在哪里调用below_shadow?视图的背景? - Arthur Melo
1
创建 below_shadow.xml 文件,然后在您的视图中,在布局中添加一个“View”,并将 below_shadow.xml 设置为此视图的背景。 - Morteza Rastgoo
我按照你说的做了,但是当我把那个视图放在自定义视图中时,我的“above_shadow”不透明。单独使用时可以正常工作。我该怎么办? - SoYoung

19
作为一种替代方案,您可以使用9 patch图像作为布局的背景,允许更加“自然”的阴影效果: enter image description here 将图片放在/res/drawable文件夹中。 确保文件扩展名为.9.png,而不是.png 顺便说一下,这是API 19 sdk资源文件夹中现有资源的修改版(缩小到最小正方形尺寸)。 我留下了红色标记,因为它们似乎没有危害,如在draw9patch工具中所示。
【编辑】
关于9 patches,如果您从未接触过它们。
只需将其添加为您的View的背景即可。
黑色标记区域(左侧和顶部)将被拉伸(垂直、水平)。 黑色标记区域(右侧、底部)定义了“内容区域”(可以在其中添加文本或视图 - 如果愿意,可以称之为“填充”未标记区域)。
教程: http://radleymarx.com/blog/simple-guide-to-9-patch/

1
只需将其添加为您视图的背景。黑色标记区域(左侧和顶部)将会拉伸(垂直,水平方向)。黑色标记区域(右侧和底部)定义了“内容区域”(可以在其中添加文本或视图 - 如果您喜欢,可以称之为“填充”)。教程:http://radleymarx.com/blog/simple-guide-to-9-patch/ - Phantômaxx

10

你需要在drawable文件夹下创建一个名为drop_shadow.xml的文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--<item android:state_pressed="true">
        <layer-list>
            <item android:left="4dp" android:top="4dp">
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp"/>
                </shape>
            </item>
            ...
        </layer-list>
    </item>-->
    <item>
        <layer-list>
            <!-- SHADOW LAYER -->
            <!--<item android:top="4dp" android:left="4dp">
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp" />
                </shape>
            </item>-->
            <!-- SHADOW LAYER -->
            <item>
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp" />
                </shape>
            </item>
            <!-- CONTENT LAYER -->
            <item android:bottom="3dp" android:left="1dp" android:right="3dp" android:top="1dp">
                <shape>
                    <solid android:color="#ffffff" />
                    <corners android:radius="1dp" />
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

那么:

<LinearLayout
...
android:background="@drawable/drop_shadow"/>

6

1.首先在“drawable”文件夹中创建一个名为shadow.xml的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="#CABBBBBB" />
                <corners android:radius="10dp" />
            </shape>
        </item>

        <item
            android:bottom="6dp"
            android:left="0dp"
            android:right="6dp"
            android:top="0dp">
            <shape android:shape="rectangle">
                <solid android:color="@android:color/white" />
                <corners android:radius="4dp" />
            </shape>
        </item>
    </layer-list>

然后将layer-list作为LinearLayout的背景添加。
<LinearLayout
        android:id="@+id/header_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shadow"
        android:orientation="vertical">

1
@Johndahat 没问题 - Sudhir Singh

4

使用这一行代码,您将获得最佳效果;

使用: android:elevation="3dp" 根据需要调整大小,这是实现按钮和其他默认Android阴影的最佳且最简单的方法。 如果有效,请告诉我!


@MichałZiobro 在布局中使用它,例如如果您有一个比另一个更小的布局,并且想要显示阴影。它应该可以工作。您可能会发现您的文本和按钮变得不可见,但是当您运行应用程序时,您将看到最好的阴影效果。我不确定这是否是某种错误或其他问题,但在我的情况下,当我使用该代码时,所有视图都在AS预览中变为不可见,但在我调试/启动设备上的应用程序中效果最佳。让我知道它是否起作用。 谢谢。 - Tamim

3
如果您已经有形状的边框,请添加高度:
<LinearLayout
    android:id="@+id/layout"
    ...
    android:elevation="2dp"
    android:background="@drawable/rectangle" />

2
API < 21 上的行为是什么? - CoolMind
1
不幸的是,它不支持Lollipop之前的版本,因此您应该使用此问题中的其他答案。但是,如果您的目标是较新的手机,则这是一种非常简单有效的方法。 - Krzynool

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