1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Android Paint 画笔使用详解 Android自定义View(六)

Android Paint 画笔使用详解 Android自定义View(六)

时间:2018-09-28 14:07:29

相关推荐

Android Paint 画笔使用详解 Android自定义View(六)

绘制在View.draw()方法里调用的,具体的执行顺序是:

drawBackground():绘制背景,不能重写。

onDraw():绘制主体。

dispatchDraw():绘制子View

onDrawForeground():绘制滑动边缘渐变、滚动条和前景。

1 绘制分析

我们如果继承View来实现自定义View。View类的onDraw()是空实现,所以我们的绘制代码写在super.onDraw(canvas)的前面或者后面都没有关系,如下所示:

public class DrawView extends View {@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制代码,写在super.onDraw(canvas)前后均可}}

但是如果我们继承特定的控件,例如TextView。我们就需要去考虑TextView的绘制逻辑。

public class DrawView extends TextView {@Overrideprotected void onDraw(Canvas canvas) {//写在前面,DrawView的绘制会先于TextView的绘制,TextView绘制的内容可以会覆盖DrawViewsuper.onDraw(canvas);//写在后面,DrawView的绘制会晚于TextView的绘制,DrawView绘制的内容可以会覆盖TextView}}

2 Paint:顾名思义,画笔,通过Paint可以对绘制行为进行控制。

2.1 颜色处理类

在Paint类中,处理颜色主要有三个方法。

setShader(Shader shader):用来处理颜色渐变setColorFilter(ColorFilter filter):用来基于颜色进行过滤处理;setXfermode(Xfermode xfermode) 用来处理源图像和 View 已有内容的关系

2.1.1 setShader(Shader shader)

着色器是图像领域的一个通用概念,它提供的是一套着色规则。着色器具体由Shader的子类实现。

2.1.1.1 线性渐变 LinearGradient

public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, TileMode tile)

参数解析:x0 y0 x1 y1:渐变的两个端点的位置,color0 color1 是端点的颜色

tile:端点范围之外的着色规则,类型是 TileMode(定义平铺模式)。TileMode 一共有 3 个值可选: CLAMP(复制边缘色彩), MIRROR (在水平和垂直方向上使用交替镜像的方式重复图片的绘制)和 REPEAT(图像平铺)。

//线性渐变 案例Shader shader1 = new LinearGradient(0, 150, 200, 150, Color.RED, Color.BLUE, Shader.TileMode.CLAMP);mPaint.setShader(shader1);Shader shader2 = new LinearGradient(0, 350, 200, 350, Color.RED, Color.BLUE, Shader.TileMode.MIRROR);mPaint2.setShader(shader2);Shader shader3 = new LinearGradient(0, 750, 200, 750, Color.RED, Color.BLUE, Shader.TileMode.REPEAT);mPaint3.setShader(shader3);canvas.drawRect(0, 100, 1000, 200, mPaint);canvas.drawRect(0, 300, 1000, 600, mPaint2);canvas.drawRect(0, 700, 1000, 1000, mPaint3);

2.1.1.2 SweepGradient - 辐射渐变

public RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, @NonNull TileMode tileMode)

参数解析:

//辐射渐变//(0,100)为辐射中心点坐标,参数200为辐射半径Shader shader1 = new RadialGradient(0, 100, 200, Color.RED, Color.BLUE, Shader.TileMode.CLAMP);mPaint.setShader(shader1);Shader shader2 = new RadialGradient(0, 300, 200, Color.RED, Color.BLUE, Shader.TileMode.MIRROR);mPaint2.setShader(shader2);Shader shader3 = new RadialGradient(0, 700, 200, Color.RED, Color.BLUE, Shader.TileMode.REPEAT);mPaint3.setShader(shader3);canvas.drawRect(0, 100, 1000, 200, mPaint);canvas.drawRect(0, 300, 1000, 600, mPaint2);canvas.drawRect(0, 700, 1000, 1000, mPaint3);

2.1.1.3 BitmapShader - 位图着色

public BitmapShader(@NonNull Bitmap bitmap, TileMode tileX, TileMode tileY)

2.1.1.4 ComposeShader - 组合Shader

ComposeShader可以将连个Shader组合在一起

public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)

PorterDuff.Mode用来指定两个Shader叠加时颜色的绘制策略,它有很多种策略,也就是以一种怎样的模式来与原图像进行合成,具体如下

2.1.2 setColorFilter(ColorFilter filter)

颜色过滤器可以将颜色按照一定的规则输出,常见于各种滤镜效果。

2.1.2.1 LightingColorFilter - 模拟光照效果

public LightingColorFilter(int mul, int add)

mul 和 add 都是和颜色值格式相同的 int 值,其中 mul 用来和目标像素相乘,add 用来和目标像素相加

//颜色过滤器ColorFilter colorFilter1 = new LightingColorFilter(Color.RED, Color.BLUE);paint2.setColorFilter(colorFilter1);

2.1.2.2 PorterDuffColorFilter - 模拟颜色混合效果

public PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode)

PorterDuffColorFilter指定一种颜色和PorterDuff.Mode来与源图像就行合成,也就是以一种怎样的模式来与原图像进行合成

//我们在使用Xfermode的时候也是使用它的子类PorterDuffXfermodeXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);canvas.drawBitmap(rectBitmap, 0, 0, paint); // 画方 paint.setXfermode(xfermode); // 设置 Xfermode canvas.drawBitmap(circleBitmap, 0, 0, paint); // 画圆 paint.setXfermode(null); // 用完及时清除 Xfermode

2.1.2.3 ColorMatrixColorFilter - 颜色矩阵过滤

ColorMatrixColorFilter使用一个颜色矩阵ColorMatrix来对象图像进行处理。

public ColorMatrixColorFilter(ColorMatrix matrix)

ColorMatrix是一个4x5的矩阵

[ a, b, c, d, e,f, g, h, i, j,k, l, m, n, o,p, q, r, s, t ]

通过计算,ColorMatrix可以对要绘制的像素进行转换,如下:

R’ = a*R + b*G + c*B + d*A + e; G’ = f*R + g*G + h*B + i*A + j; B’ = k*R + l*G + m*B + n*A + o; A’ = p*R + q*G + r*B + s*A + t;

2.2 文字处理类

Paint里有大量方法来设置文字的绘制属性,事实上文字在Android底层是被当做图片来处理的。

2.3 特殊效果类
2.3.1 setAntiAlias (boolean aa)设置抗锯齿

默认关闭,用来是图像的绘制更加圆润。我们还可以在初始化的时候设置Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);。

2.3.2 setStyle(Paint.Style style) 设置填充风格

如果是划线模式,我们针对线条还可以有多种设置

setStrokeWidth(float width) - 设置线条粗细

setStrokeCap(Paint.Cap cap) - 设置线头的形状,默认为 BUTT

UTT 平头ROUND 圆头SQUARE 方头

setStrokeJoin(Paint.Join join) - 设置拐角的形状。默认为 MITER

MITER 尖角BEVEL 平角ROUND 圆角

setStrokeMiter(float miter)- 设置 MITER 型拐角的延长线的最大值

2.3.3 setDither(boolean dither) 设置图像的抖动。
2.3.3 setFilterBitmap(boolean filter)设置是否使用双线性过滤来绘制 Bitmap

图像在放大绘制的时候,默认使用的是最近邻插值过滤,这种算法简单,但会出现马赛克现象;而如果开启了双线性过滤,就可以让结果图像显得更加平滑。

etPathEffect(PathEffect effect)

2.3.4 设置图形的轮廓效果。Android有六种PathEffect:

//图形轮廓效果//绘制圆角 参数 20 为圆角半径PathEffect cornerPathEffect = new CornerPathEffect(20);paint1.setStyle(Paint.Style.STROKE);paint1.setStrokeWidth(5);paint1.setPathEffect(cornerPathEffect);//绘制尖角 float segmentLength:用来拼接每个线段的长度,float deviation:偏离量PathEffect discretePathEffect = new DiscretePathEffect(20, 5);paint2.setStyle(Paint.Style.STROKE);paint2.setStrokeWidth(5);paint2.setPathEffect(discretePathEffect);//绘制虚线//float[] intervals:指定了虚线的格式,数组中元素必须为偶数(最少是 2 个),按照「画线长度、空白长度、画线长度、空白长度」……的顺序排列float phase:虚线的偏移量PathEffect dashPathEffect = new DashPathEffect(new float[]{20,10, 5, 10}, 0);paint3.setStyle(Paint.Style.STROKE);paint3.setStrokeWidth(5);paint3.setPathEffect(dashPathEffect);//使用path来绘制虚线Path path = new Path();//画一个三角来填充虚线path.lineTo(40, 40);path.lineTo(0, 40);path.close();PathEffect pathDashPathEffect = new PathDashPathEffect(path, 40, 0, PathDashPathEffect.Style.TRANSLATE);paint4.setStyle(Paint.Style.STROKE);paint4.setStrokeWidth(5);paint4.setPathEffect(pathDashPathEffect);

2.3.5 setShadowLayer(float radius, float dx, float dy, int shadowColor)设置阴影图层

处于目标下层图层

参数说明

2.3.6 setMaskFilter(MaskFilter maskfilter)

设置图层遮罩层,处于目标上层图层。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。