关于 Android 阴影,大家肯定不陌生的。但是Android 中到底有多少种方式可以实现阴影效果以及各种方式之间有什么区别和优缺点,这就是我想总结的。下面我们一个一个来说:
一、各种实现阴影的方式
1. Android 在 API 21(5.0)添加了 elevation,可以很方便的在 View 上实现阴影。但是这个只在 >= API21 的手机上可以看到阴影效果,低于这个版本的就没有阴影效果。目前市场上应用还是需要适配至 API15 的,所以需要慎重使用。
2. CardView 也可以实现阴影效果,项目中一般都是使用这种方式实现卡片式的效果并带有阴影。使用 CardView 确实很不错,但是它在使用的时候也是需要有注意的地方:
(1) CardView 实现阴影效果的布局,在 >= API 21 的版本上和 < 21 的版本上,如果不在代码上做好控制,他们的显示差异还是很大的。至于如何进行适配,可以自行查找。有图有真相:大小呈现差异,阴影有差异:测试机型都一致,只有Android 版本差异,对于左下角的 cardBackgroundcolor 透明也是有差异的。左侧为 API 15 、 右侧为 API 22
(2) CardView 在 >= API21 的版本上实现阴影效果也是通过 elevation 来实现的,最终的渲染是调用 native 方法进行的。在使用过程中发现这样一个问题,在不同位置的 View 阴影的方向是不一样的。不知道你们发现没,它模拟的场景就是 光源的位置在屏幕中心的正上方,然后 View 的位置由光源的位置决定。阴影方向不一致,这一点造成了我在开发中的一个 BUG,很头痛啊,这也是一个 BUG,后面会有解决这个 。有图有真相:
(3)如果有对阴影颜色有要求的需求, CardView 不好意思,臣妾做不到啊。哈哈,CardView 黑的差不多了。
3. Shape 来实现阴影。通过这种方式来实现阴影,由于shape是作为背景来使用的,阴影的存在有可能使内容显示在阴影部分即阴影也占位哈。硬伤啊,当然你可以手动设置 margin 或者 padding 值控制内容的显示位置,当然要是 dp 适配的哈。我们来看一下 shape 如何实现阴影:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!--边--> <item> <shape android:shape="rectangle"> <padding android:bottom="2px" android:left="1px" android:right="2px" android:top="1px" /> <solid android:color="#00CCCCCC" /> <corners android:radius="5dp" /> </shape> </item> <item> <shape android:shape="rectangle"> <padding android:bottom="2px" android:left="1px" android:right="2px" android:top="1px" /> <solid android:color="#10CCCCCC" /> <corners android:radius="5dp" /> </shape> </item> <item> <shape android:shape="rectangle"> <padding android:bottom="2px" android:left="1px" android:right="2px" android:top="1px" /> <solid android:color="#20CCCCCC" /> <corners android:radius="5dp" /> </shape> </item> <item> <shape android:shape="rectangle"> <padding android:bottom="2px" android:left="1px" android:right="2px" android:top="1px" /> <solid android:color="#30CCCCCC" /> <corners android:radius="5dp" /> </shape> </item> <item> <shape android:shape="rectangle"> <padding android:bottom="2px" android:left="1px" android:right="2px" android:top="1px" /> <solid android:color="#50CCCCCC" /> <corners android:radius="5dp" /> </shape> </item> <!--中心背景 --> <item> <shape android:shape="rectangle" android:useLevel="false"> <!--实心 --> <solid android:color="@color/white_f2" /> <corners android:radius="5dp" /> <size android:width="32dp" android:height="32dp"/> </shape> </item> </layer-list>