前言
根据启舰 的博客所学习的自定义View。
一、setShadowLayer构造函数
public void setShadowLayer(float radius, float dx, float dy, int color)
- radius:模糊半径,radius越大越模糊,越小越清晰,但是如果radius设置为0,则阴影消失不见
- dx:阴影的横向偏移距离,正值向右偏移,负值向左偏移
- dy:阴影的纵向偏移距离,正值向下偏移,负值向上偏移
- color: 绘制阴影的画笔颜色,即阴影的颜色(对图片阴影无效)
注意:这里有一点需要非常注意的是setShadowLayer只有文字绘制阴影支持硬件加速,其它都不支持硬件加速,所以为了方便起见,我们需要在自定义控件中禁用硬件加速。
二、实现对文本,图形,Image的阴影效果
void init(){
setLayerType(LAYER_TYPE_SOFTWARE, null);//对单独的View在运行时阶段禁用硬件加速
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.RED);
paint.setStrokeWidth(2);
paint.setAntiAlias(true);
paint.setTextSize(50);
paint.setShadowLayer(5, 15, 20, Color.GREEN);
canvas.drawText("demo", 100, 100, paint);
canvas.drawCircle(200, 200, 50, paint);
canvas.drawBitmap(bitmap, null, new RectF(200, 300, 200 + bitmap.getWidth(), 300 + bitmap.getHeight()), paint);
}
三、 清除与显示阴影
- 显示阴影就调用paint.setShadowLayer方法
- 清除阴影就调用paint.clearShadowLayer()
四、TextView及其派生类使用ShadowLayer添加阴影效果
直接上代码⤵️
<TextView
…………
android:shadowRadius="3"
android:shadowDx="5"
android:shadowDy="5"
android:shadowColor="@android:color/darker_gray"/>
或者
TextView tv = (TextView)findViewById(R.id.tv);
tv.setShadowLayer(2,5,5, Color.GREEN);
五、SetMaskFilter之BlurMaskFilter实现发光效果
与setShadowLayer一样,发光效果也是使用的高斯模糊,并且只会影响边缘部分图像,内部图像是不受影响的
发光效果是无法指定发光颜色的,采用边缘部分的颜色取样来进行模糊发光。所以边缘是什么颜色,发出的光也就是什么颜色的。
1. 基本方法
public MaskFilter setMaskFilter(MaskFilter maskfilter)
public BlurMaskFilter(float radius, Blur style)
- float radius:用来定义模糊半径,同样是高斯模糊算法。
- Blur style:发光样式,有内发光、外发光、和内外发光,分别对应:Blur.INNER(内发光)、Blur.SOLID(外发光)、Blur.NORMAL(内外发光)、Blur.OUTER(仅发光部分可见),
void init(){
......
setLayerType(LAYER_TYPE_SOFTWARE, null);//对单独的View在运行时阶段禁用硬件加速
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
canvas.drawText("正常",30,100,paint);
Paint paint1 = new Paint();
paint1.setColor(Color.RED);
paint1.setStyle(Paint.Style.FILL);
canvas.drawCircle(300, 100, 50, paint1);
canvas.drawText("INNER",0,250,paint);
Paint paint2 = new Paint();
paint2.setColor(Color.RED);
paint2.setStyle(Paint.Style.FILL);
paint2.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.INNER));
canvas.drawCircle(300, 250, 50, paint2);
canvas.drawText("OUTER",0,400,paint);
Paint paint3 = new Paint();
paint3.setColor(Color.RED);
paint3.setStyle(Paint.Style.FILL);
paint3.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.OUTER));
canvas.drawCircle(300, 400, 50, paint3);
canvas.drawText("NORMAL",0,550,paint);
Paint paint4 = new Paint();
paint4.setColor(Color.RED);
paint4.setStyle(Paint.Style.FILL);
paint4.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.NORMAL));
canvas.drawCircle(300, 550, 50, paint4);
}
2. 图片发光
其实实现方式和上边的一样的,不过,这里我们先说一个小知识** extraAlpha()函数**:
extractAlpha()新建一张仅具有Alpha值的空白图像
这张图像的颜色,是由canvas.drawBitmap时的画笔指定的。
举个栗子:
void init(){
......
setLayerType(LAYER_TYPE_SOFTWARE, null);//对单独的View在运行时阶段禁用硬件加速
}
//初始化
private void initBitmap() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.bear);
mBitmap = bitmap.extractAlpha();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
paint.setColor(Color.GREEN);
canvas.drawBitmap(mBitmap, null, new RectF(100, 100, 100 + mBitmap.getWidth(), mBitmap.getHeight() + 100), paint);
canvas.drawBitmap(bitmap, null, new RectF(100, 300, 100 + bitmap.getWidth(), bitmap.getHeight() + 300), paint);
}
那么,接下来我们就将这两个图发光吧!
其实还是这两句话,哈哈
mPaint.setColor(mShadowColor);//设置发光的颜色
mPaint.setMaskFilter(new BlurMaskFilter(mRadius, BlurMaskFilter.Blur.NORMAL));//设置发光样式,NORMAL是内外发光
具体源码:
setLayerType(LAYER_TYPE_SOFTWARE, null);//对单独的View在运行时阶段禁用硬件加速
paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
paint.setColor(Color.GREEN);
canvas.drawBitmap(mBitmap, null, new RectF(100, 100, 100 + mBitmap.getWidth(), mBitmap.getHeight() + 100), paint);
paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
canvas.drawBitmap(bitmap, null, new RectF(100, 300, 100 + bitmap.getWidth(), bitmap.getHeight() + 300), paint);
效果图为【可以对比上面未发光的效果图】:
后记
由于作者君偷懒,所以paint的创建呀什么的,全都放在onDraw里面了,大家写代码的时候,要使onDraw轻量。不要直接放进去,在外面初始化哈~
感谢大家提出的问题,笔芯~