在 Android 上为自定义形状添加阴影
Posted
技术标签:
【中文标题】在 Android 上为自定义形状添加阴影【英文标题】:Add shadow to custom shape on Android 【发布时间】:2011-03-04 18:40:05 【问题描述】:是否可以在 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>
【问题讨论】:
【参考方案1】:找了好久终于找到了
<?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>
【讨论】:
你在哪里配置<!-- Bottom 2dp Shadow -->
我在你的代码中没有看到任何2
...???【参考方案2】:
这就是我的做法:
一键状态代码如下:
<?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>
希望这可以帮助你..祝你好运
【讨论】:
【参考方案3】:这是我的投影版本。我打算在形状周围画一个朦胧的阴影,并使用this answer by 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>
【讨论】:
工作正常.. 谢谢(y)【参考方案4】:我觉得这个方法效果很好:
<!-- 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:/>
<solid android:color="#FFF" />
<corners android:radius="2dp" />
</shape>
</item>
【讨论】:
【参考方案5】:以下内容对我有用:只需另存为 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>
【讨论】:
【参考方案6】:我建议对 Bruce 的解决方案进行小幅改进,即防止在彼此之上过度绘制相同的形状,并简单地使用笔触而不是实体。 它看起来像这样:
<?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: />
<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: />
<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: />
<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: />
<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: />
<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: />
<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: />
<corners android:radius="3dp" />
</shape>
</item>
<!-- Background -->
<item>
<shape>
<solid android:color="#FFF" />
<corners android:radius="3dp" />
</shape>
</item>
</layer-list>
最后,我想为那些想要在特定方向上的阴影的人指出,你所要做的就是将顶部、底部、左侧或右侧设置为 0dp(实线)或 -1dp(无)
【讨论】:
【参考方案7】:Material Design 提供的旧问题,但 Elevation 现在可为任何视图提供阴影。
<TextView
android:id="@+id/myview"
...
android:elevation="2dp"
android:background="@drawable/myrect" />
请参阅https://developer.android.com/training/material/shadows-clipping.html 上的文档
【讨论】:
如果您有几个 UI 小部件,它们应该在最外面的形状周围出现一个阴影,该怎么办?我尝试向外部添加高度,但内部则隐藏在外部之后。所以我尝试为两者添加高程,但看起来内部的在外部的顶部有一个阴影,就像印加金字塔一样。 我最终通过使用单个ImageButton
而不是 ImageView
加上 Button' because it allows a
ImageButton 来处理融合,同时允许 android:background
和 android:src
。因此,我能够只指定一次android:elevation
,并避免了我在上一条评论中描述的“印加金字塔效应”。【参考方案8】:
如果您不介意使用 Canvas API 进行一些自定义绘图,请查看有关 drop shadows 的答案。这是一个follow-up 问题,可以解决原始问题。
【讨论】:
【参考方案9】: <?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:
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>
【讨论】:
【参考方案10】:这个问题可能很老了,但对于任何想要一种简单的方法来实现复杂阴影效果的人来说,请在这里查看我的库https://github.com/BluRe-CN/ComplexView
使用该库,您可以更改阴影颜色、调整边缘等等。这是一个实现您所寻求的示例。
<com.blure.complexview.ComplexView
android:layout_
android:layout_
app:radius="10dp"
app:shadow="true"
app:shadowSpread="2">
<com.blure.complexview.ComplexView
android:layout_
android:layout_
app:color="#fdfcfc"
app:radius="10dp" />
</com.blure.complexview.ComplexView>
要更改阴影颜色,请使用 app:shadowColor="your color code"。
【讨论】:
【参考方案11】:9个补丁,轻松实现漂亮的阴影 尤其是这个很棒的工具 -
Android 9-patch shadow generator
PS:如果项目无法编译,您需要在 android studio 编辑器中移动黑线一点
【讨论】:
【参考方案12】:我认为这个阴影值在大多数情况下都很好:
<solid android:color="#20000000" />
【讨论】:
【参考方案13】:如果您需要直线阴影(如工具栏底部),您也可以使用渐变 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>
希望对某人有所帮助
【讨论】:
【参考方案14】:如果您在自定义背景可绘制对象上设置 <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:/>
<corners android:radius="@dimen/card_corner_radius" />
</shape>
</item>
</layer-list>
【讨论】:
【参考方案15】:只需将海拔设置为 10 左右。 https://developer.android.com/training/material/shadows-clipping
【讨论】:
以上是关于在 Android 上为自定义形状添加阴影的主要内容,如果未能解决你的问题,请参考以下文章
如何将 MKMapView(或任何 UIView)裁剪为自定义形状?
Android Gradle 插件自定义 Gradle 任务 ⑤ ( 为自定义 Gradle 任务添加依赖任务 | Gradle 任务依赖执行顺序控制 )
Android Gradle 插件自定义 Gradle 任务 ⑤ ( 为自定义 Gradle 任务添加依赖任务 | Gradle 任务依赖执行顺序控制 )