Android控件的阴影效果的实现方式有很多种,这里介绍一下另一种Android原生的阴影实现方案(API28及以上)。
1、阴影原理
阴影效果的实现采用的是Android原生的View的属性,拔高Z轴。Z轴会让View产生阴影的效果:
可以理解为有一束斜光投向屏幕,Z 轴值越大,离光就越近,阴影的范围就越大;Z 轴值越小,离光就越远,阴影的范围就越小。
2、Z轴
Z=elevation+ translationZ
拔高Z轴可以通过控制elevation和translationZ。区别:
elevation:一般是写在 xml 文件中做静态配置,单纯的控制Z轴;
translateZ:除了控制Z轴,还可以用来控制动画效果,比如我们点击按钮时希望它有一个弹起的效果:
由于我们只需要实现阴影效果,所以这里只配置elevation即可。
3、如何设置阴影?
阴影的效果由Z轴(elevation)、光源(shadowColor)和环境阴影透明度(ambientShadowAlpha)三者综合决定的。所以我们需要对这三者进行合理的设置:
Z轴(elevation)
直接在需要产生阴影的布局根布局里设置elevation即可;
光源(shadowColor)
产生阴影的光源有两个:主光源(key light)和环境光源(ambient light)。实际产生的阴影是由这两个光源组合产生的。
光源分布的位置:
看看各个光源的展示效果:
具体代码:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="250dp"
android:layout_height="match_parent"
android:background="@drawable/common_bg"
android:elevation="25dp"
android:outlineAmbientShadowColor="#B309101D"
android:outlineSpotShadowColor="@color/transparent">
...
</androidx.constraintlayout.widget.ConstraintLayout>
elevation:设置Z轴
outlineSpotShadowColor:设置主光源
outlineAmbientShowColor:设置环境光源
环境阴影透明度(ambientShadowAlpha)
环境阴影透明度是通过主题theme设置的:
<style name="AppTheme" parent="Theme">
...
<item name="android:ambientShadowAlpha">1</item>
...
</style>
透明度的取值为0-1,可根据实际情况来调试。
4、注意事项
除了设置上面的三个条件Z轴(elevation)、光源(shadowColor)和环境阴影透明度(ambientShadowAlpha),还有其他几个点需要注意的:
- 一定要设置背景,而且是不透明的背景,因为阴影是通过投影来产生的,没有或透明的背景是无法产生的阴影的。设置了背景就一定会产生阴影?不一定,这里感觉有bug,有些背景图片无法产生阴影,网上查了一下,也有人遇到:在background是图片时、直接设置具体颜色值时容易无效,比如:#ffaacc。感觉background设置为点9图和shape时效果最好;
- 阴影是绘制在父控件的空间上的,所以在子控件和父控件的边界之间要留一定的空间来绘制阴影;
- 设置elevation的View最好是ViewGroup的子类;
5、总结
总结起来,设置阴影就需要:
- 设置Z轴(elevation);
- 光源:outlineSpotShadowColor(主光源)、outlineAmbientShowColor(环境光源);
- 环境阴影透明度(ambientShadowAlpha);
- 设置不透明背景(background);
- 留出阴影绘制空间;