在 Android 上为自定义形状添加阴影

是否可以在 Android 中为自定义形状添加阴影?在浏览了文档之后,我只看到了一种应用文本阴影的方法。

我尝试过这种方法,但运气不佳:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#90ffffff"/>
<corners android:radius="12dp" />
<item name="android:shadowColor">#000000</item>
<item name="android:shadowRadius">5</item>
<item name="android:shadowDy">3</item>
</shape>
253276 次浏览

如果您不介意使用 Canvas API 进行一些自定义绘图,请查看关于 投下阴影的这个答案。这里有一个 跟进问题,解决了原来的一个问题。

下面的方法对我很有用: 保存为 custom_ shape.xml。

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


<!-- "shadow" -->
<item>
<shape android:shape="rectangle" >
<solid android:color="#000000"/>
<corners android:radius="12dp" />
</shape>
</item>




<item android:bottom="3px">
<shape android:shape="rectangle">
<solid android:color="#90ffffff"/>
<corners android:radius="12dp" />
</shape>
</item>


</layer-list>

我认为这个阴影值在大多数情况下是有用的:

<solid android:color="#20000000" />

我是这么做的:

Android Native Button with Shadows

下面是一个按钮的代码状态:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- "background shadow" -->
<item>
<shape android:shape="rectangle" >
<solid android:color="#000000" />


<corners android:radius="15dp" />
</shape>
</item>
<!-- background color -->
<item
android:bottom="3px"
android:left="3px"
android:right="3px"
android:top="3px">
<shape android:shape="rectangle" >
<solid android:color="#cc2b2b" />




<corners android:radius="8dp" />
</shape>
</item>
<!-- over left shadow -->
<item>
<shape android:shape="rectangle" >
<gradient
android:angle="180"
android:centerColor="#00FF0000"
android:centerX="0.9"
android:endColor="#99000000"
android:startColor="#00FF0000" />


<corners android:radius="8dp" />
</shape>
</item>
<!-- over right shadow -->
<item>
<shape android:shape="rectangle" >
<gradient
android:angle="360"
android:centerColor="#00FF0000"
android:centerX="0.9"
android:endColor="#99000000"
android:startColor="#00FF0000" />


<corners android:radius="8dp" />
</shape>
</item>
<!-- over top shadow -->
<item>
<shape android:shape="rectangle" >
<gradient
android:angle="-90"
android:centerColor="#00FF0000"
android:centerY="0.9"
android:endColor="#00FF0000"
android:startColor="#99000000"
android:type="linear" />


<corners android:radius="8dp" />
</shape>
</item>
<!-- over bottom shadow -->
<item>
<shape android:shape="rectangle" >
<gradient
android:angle="90"
android:centerColor="#00FF0000"
android:centerY="0.9"
android:endColor="#00FF0000"
android:startColor="#99000000"
android:type="linear" />


<corners android:radius="8dp" />
</shape>
</item>
</layer-list>

然后你应该有一个不同版本的按钮选择器,比如:

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


<item android:drawable="@drawable/ic_button_red_pressed" android:state_pressed="true"/> <!-- pressed -->
<item android:drawable="@drawable/ic_button_red_selected" android:state_focused="true"/> <!-- focused -->
<item android:drawable="@drawable/ic_button_red_selected" android:state_selected="true"/> <!-- selected -->
<item android:drawable="@drawable/ic_button_red_default"/> <!-- default -->


</selector>

希望这个能帮到你,祝你好运

我认为这种方法产生了很好的效果:

<!-- Drop Shadow Stack -->
<item>
<shape>
<padding
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
android:left="1dp"/>
<solid android:color="#00CCCCCC"/>
</shape>
</item>
<item>
<shape>
<padding
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
android:left="1dp"/>
<solid android:color="#10CCCCCC"/>
</shape>
</item>
<item>
<shape>
<padding
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
android:left="1dp"/>
<solid android:color="#20CCCCCC"/>
</shape>
</item>
<item>
<shape>
<padding
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
android:left="1dp"/>
<solid android:color="#30CCCCCC"/>
</shape>
</item>
<item>
<shape>
<padding
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
android:left="1dp"/>
<solid android:color="#50CCCCCC"/>
</shape>
</item>


<item>


<shape android:shape="rectangle">
<stroke android:color="#CCC" android:width="1dp"/>
<solid android:color="#FFF" />
<corners android:radius="2dp" />


</shape>


</item>

经过大量的搜索,我终于找到了这个

enter image description here

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


<!-- Bottom 2dp Shadow -->
<item>
<shape  android:shape="rectangle">


<solid android:color="#d8d8d8" />
<corners android:radius="7dp" />


</shape>
</item>


<!-- White Top color -->
<item android:bottom="3px">


<shape  android:shape="rectangle">


<solid android:color="#FFFFFF" />
<corners android:radius="7dp" />




</shape>


</item>




</layer-list>

这是我的投影。我是为了一个模糊的阴影周围的形状和使用 这个答案Joakim Lundborg作为我的出发点。我改变的是添加角落的所有阴影项目和增加角落的半径为每个随后的阴影项目。这就是 xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack -->
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#02000000" />
<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>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#25000000" />
<corners android:radius="3dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<solid android:color="#30000000" />
<corners android:radius="3dp" />
</shape>
</item>


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

enter image description here

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


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


<stroke
android:width="1dp"
android:color="@color/LightGrey" >
</stroke>


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


<corners
android:bottomLeftRadius="20dp"
android:bottomRightRadius="20dp"
android:radius="12dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp" />


<gradient
android:angle="90"
android:centerColor="@android:color/white"
android:centerY="0.2"
android:endColor="#99e0e0e0"
android:startColor="@android:color/white"
android:type="linear" />


</shape>

旧的问题,但是海拔,可与材料设计现在提供一个阴影的任何意见。

<TextView
android:id="@+id/myview"
...
android:elevation="2dp"
android:background="@drawable/myrect" />

https://developer.android.com/training/material/shadows-clipping.html看医生

如果你需要一个直线阴影(如在工具栏底部) ,你也可以使用渐变 xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:type="linear"
android:angle="-90"
android:startColor="#19000000" <!-- black transparent -->
android:endColor="#00000000" /> <!-- full transparent -->
</shape>

希望这能帮到某人

我想对布鲁斯的解决方案提出一个小小的改进,那就是防止相同的形状互相叠加,并简单地使用笔划代替实体。 它看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Drop Shadow Stack -->
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<stroke android:color="#02000000" android:width="1dp"  />
<corners android:radius="8dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<stroke android:color="#05000000" android:width="1dp" />
<corners android:radius="7dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<stroke android:color="#10000000" android:width="1dp" />
<corners android:radius="6dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<stroke android:color="#15000000" android:width="1dp" />
<corners android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<stroke android:color="#20000000" android:width="1dp" />
<corners android:radius="4dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<stroke android:color="#25000000" android:width="1dp" />
<corners android:radius="3dp" />
</shape>
</item>
<item>
<shape>
<padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" />
<stroke android:color="#30000000" android:width="1dp" />
<corners android:radius="3dp" />
</shape>
</item>


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

screenshot of the rendering of the shadow 最后,我想指出的人谁想要一个特定方向的阴影,你所要做的就是设置顶部,底部,左或右为0dp (一个实线)或 -1 dp (无)

这个问题可能已经过时了,但是对于任何想要一个简单的方法来实现复杂的阴影效果的人来说,可以在这里查看我的图书馆 https://github.com/BluRe-CN/ComplexView

使用这个库,你可以改变阴影的颜色,调整边缘等等。这里有一个实现你所追求的目标的例子。

<com.blure.complexview.ComplexView
android:layout_width="400dp"
android:layout_height="600dp"
app:radius="10dp"
app:shadow="true"
app:shadowSpread="2">


<com.blure.complexview.ComplexView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:color="#fdfcfc"
app:radius="10dp" />
</com.blure.complexview.ComplexView>

要更改阴影颜色,请使用 app: ShadowColor = “ your color code”。

9补丁救援,漂亮的阴影可以很容易地实现 特别是用这个可怕的工具

Android 9-patch 阴影生成器

附注: 如果项目将不能编译,你将需要移动黑线在 android 工作室编辑器一点点

由于某些原因,如果在自定义背景绘制上设置 <solid><stroke>,阴影就不起作用。创建一个具有单独的填充层和边框的 <layer-list>解决了这个问题:

<?xml version="1.0" encoding="utf-8"?>
<!-- Separate layers for solid and stroke, because no shadows get drawn otherwise (using elevation) -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/card_default" />
<corners android:radius="@dimen/card_corner_radius" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<stroke android:color="@color/card_border" android:width="@dimen/card_border_width"/>
<corners android:radius="@dimen/card_corner_radius" />
</shape>
</item>
</layer-list>
            <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="3dp"
android:left="5dp"
android:right="5dp"
android:top="5dp">
<shape android:shape="rectangle">
<gradient
android:startColor="@color/white"
android:endColor="@color/gray"
android:angle="270"
android:dither="false"/>
<corners android:radius="@dimen/_20dp" />
</shape>
</item>
<item
android:bottom="6dp"
android:left="6dp"
android:right="6dp"
android:top="6dp">
<shape android:shape="rectangle">
<solid android:color="@color/orange" />
<corners android:radius="@dimen/_20dp" />
</shape>
</item>
</layer-list>