背景
因为需要给控件四周添加一层均匀的阴影,而使用CardView给控件所添加的阴影其实不是均匀分布在四周的,而是点光源和自然光组合照射的结果,这种情况下控件底边阴影颜色最深。看图会更清晰:
shadow.png所以重新找其他替代的控件,在Github找到一个给View添加阴影控件shadow-layout能够给控件四周添加均匀阴影。不过在使用的过程中发现了一些问题。
遇到的问题
ShadowLayout有一个color属性app:sl_shadowColor="#ff0000"
,但是当我修改阴影颜色时,无论修改什么颜色,阴影颜色始终是黑色。
问题原因
这就让我很困惑了,明明修改了颜色,为什么没有起作用?在自定义的ShadowLayout控件文件里,在获取颜色值的位置添加断点,发现实际上是能获取到颜色值的。这让我更加困惑。
mShadowColor = attr.getColor(R.styleable.ShadowLayout_sl_shadowColor, getResources().getColor(R.color.default_shadow_color));
既然color确定是已经获取到,那问题应该是出在其他地方。只能从源码找问题了,查看ShadowLayout代码,发现阴影是通过绘制Bitmap来实现的,关键代码如下:
private Bitmap createShadowBitmap(int shadowWidth, int shadowHeight, float cornerRadius, float shadowRadius,
float dx, float dy, int shadowColor, int fillColor) {
//关键代码
Bitmap output = Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas(output);
//省略部分代码
Paint shadowPaint = new Paint();
shadowPaint.setAntiAlias(true);
shadowPaint.setColor(fillColor);
shadowPaint.setStyle(Paint.Style.FILL);
if (!isInEditMode()) {
shadowPaint.setShadowLayer(shadowRadius, dx, dy, shadowColor);
}
canvas.drawRoundRect(shadowRect, cornerRadius, cornerRadius, shadowPaint);
return output;
}
关键代码:
Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ALPHA_8);
可以看到,因为源代码中使用Bitmap.Config.ALPHA_8来记录颜色,而ALPHA_8只有透明度通道,只会保存透明度数据,所以无论我怎么修改颜色只有阴影的透明度在变化。
解决办法
问题原因找到了,那接下来就想办法怎么处理了。Bitmap.Config是个枚举类,除了ALPHA_8,分别还有RGB_565、ARGB_4444(Deprecated)、ARGB_8888三种类型。
四种枚举类型说明如下:
ARGB_8888:ARGB 四个通道的值都是 8 位,加起来 32 位,也就是 4 个字节。每个像素点占用 4 个字节的大小。
ARGB_4444:ARGB 四个通道的值都是 4 位,加起来 16 位,也就是 2 个字节。每个像素点占用 2 个字节的大小。
RGB_565:RGB 三个通道分别是 5 位、6 位、5 位,没有 A 通道,加起来 16 位,也就是 2 个字节。每个像素点占用 2 个字节的大小。
ALPHA_8:只有 A 通道,占 8 位,1 个字节。每个像素点占用 1 个字节的大小。
因为要修改颜色和透明度,所以既需要记录透明度(A),也需要记录颜色值(RGB),所以可以选择ARGB_8888或者ARGB_4444就能修改阴影颜色了。而使用ARGB_4444保存的图片质量太差,官方不建议使用,那么使用ARGB_8888就没问题了。
成功修改阴影颜色的图:
改变阴影颜色.png如果对你有帮助的话,喜欢、评论、赞赏都是对我的鼓励,也是支持我写下去的动力,谢谢!
网友评论