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)
参数解析:
参数名 | 参数值 |
---|---|
centerX centerY | 辐射中心的坐标 |
radius | 辐射半径 |
centerColor | 辐射中心的颜色 |
edgeColor | 辐射边缘的颜色 |
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)
参数名 | 参数值 |
---|---|
bitmap | 用来做模板的 Bitmap 对象 |
tileX | 横向的 TileMode |
tileY | 纵向的 TileMode。 |
2.1.1.4 ComposeShader - 组合Shader
ComposeShader可以将连个Shader组合在一起
public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
参数名 | 参数值 |
---|---|
shaderA, shaderB | 两个相继使用的 Shader |
mode | 两个 Shader 的叠加模式,即 shaderA 和 shaderB 应该怎样共同绘制。它的类型是PorterDuff.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的时候也是使用它的子类PorterDuffXfermode
Xfermode 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底层是被当做图片来处理的。
方法 | 解说 |
---|---|
setTextSize(float textSize) | 设置文字大小 |
setTypeface(Typeface typeface) | 设置文字字体 |
setFakeBoldText(boolean fakeBoldText) | 是否使用伪粗体(并不是提到size,而是在运行时描粗的) |
setStrikeThruText(boolean strikeThruText) | 是否添加删除线 |
setUnderlineText(boolean underlineText) | 是否添加下划线 |
setTextSkewX(float skewX) | 设置文字倾斜度 |
setTextScaleX(float scaleX) | 设置文字横向缩放 |
setLetterSpacing(float letterSpacing) | 设置文字间距 |
setFontFeatureSettings(String settings) | 使用CSS的font-feature-settings的方式来设置文字。 |
setTextAlign(Paint.Align align) | 设置文字对齐方式 |
setTextLocale(Locale locale) | 设置文字Local |
setHinting(int mode) | 设置字体Hinting(微调),过向字体中加入 hinting 信息,让矢量字体在尺寸过小的时候得到针对性的修正,从而提高显示效果。 |
setSubpixelText(boolean subpixelText) | 设置次像素级抗锯齿,根据程序所运行的设备的屏幕类型,来进行针对性的次像素级的抗锯齿计算,从而达到更好的抗锯齿效果。 |
2.3 特殊效果类
2.3.1 setAntiAlias (boolean aa)设置抗锯齿
默认关闭,用来是图像的绘制更加圆润。我们还可以在初始化的时候设置Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);。
2.3.2 setStyle(Paint.Style style) 设置填充风格
设置值 | 解析 |
---|---|
FILL 模式 | 填充 |
STROKE 模式 | 画线 |
FILL_AND_STROKE 模式 | 填充 + 画线 |
如果是划线模式,我们针对线条还可以有多种设置
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:
属性值 | 解说 |
---|---|
CornerPathEffect | 将拐角绘制成圆角 |
DiscretePathEffect | 将线条进行随机偏离 |
DashPathEffect | 绘制虚线 |
PathDashPathEffect | 使用指定的Path来绘制虚线 |
SumPathEffect | 组合两个PathEffect,叠加应用。 |
ComposePathEffect | 组合两个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)设置阴影图层
处于目标下层图层
参数说明
参数名 | 说明 |
---|---|
float radius | 阴影半径 |
float dx | 阴影偏移量 |
float dy | 阴影偏移量 |
int shadowColor | 阴影颜色 |
2.3.6 setMaskFilter(MaskFilter maskfilter)
设置图层遮罩层,处于目标上层图层。
Android Paint 画笔使用详解 Android自定义View(六)相关推荐
- android常用技术网站收藏过的网址 给 Android 开发者的 RxJava 详解 Android设备标识-没有完美的解决方案-只有取舍 - 小彼得的专栏 - 博客频道 - CSDN.NET
收藏过的网址 http://www.jianshu.com/p/a7b36d682b6f?ref=myread Android插件化快速入门与实例解析 http://www.cnblogs.com/ ...
- android uri图片压缩,详解android 通过uri获取bitmap图片并压缩
详解android 通过uri获取bitmap图片并压缩 很多人在调用图库选择图片时会在onactivityresult中用media.getbitmap来获取返回的图片,如下: uri mimage ...
- android:stretchcolumns=quot;*quot;,详解Android TableLayout中stretchColumns、shrinkColumns的用法...
详解Android 中TableLayout中stretchColumns.shrinkColumns的用法 android:stretchColumns="1" android: ...
- android led闪烁功能,详解Android应用层制作LED指示灯
详解Android应用层制作LED指示灯 在Java应用层修改LED指示灯的颜色,这个花了我半天时间, 才实现该功能! public class LEDActivity extends Activit ...
- Android Paint set方法详解
一.前言 我们用set方法来设置画笔的样式,类似于我们挑选画笔画画的过程.由于上面有些方法不支持硬件加速,所以在高版本系统中可能会没有效果.因此,我们首先来看看官方废弃的方法. 下图来自: https ...
- android任务 进程 线程详解,Android任务、进程、线程详解
singleTop模式,基本上于standard分歧,仅正在请求的Activity反好位于栈顶时,无所区别.此时,配放成singleTop的Activity,不再会构制新的实例加入到Task栈外,而是 ...
- Android编程之SparseArrayE详解
Android编程之SparseArrayE详解
Android编程之SparseArray<E>详解 分类:Android2012-09-01 13:139412人阅读评论(5)收藏举报 android编程delete存储list 最近 ...
- android布局优化 工具,详解Android布局优化
怎样才能写出优秀的Android App,是每一个程序员追求的目标.那么怎么才能写出一个优秀的App呢?相信很多初学者也会有这种迷茫.一句话来回答这个问题:细节很重要.今天我们就从最基础的XML布局来 ...
- android事件处理主要方法,详解Android的两种事件处理机制
UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理. 对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事 ...
最新文章
- 敏捷个人手机应用:如何使用时中法目标
- Oozie和Azkaban的技术选型和对比
- 【杂谈】一个五岁孩子妈妈在有三AI学习并且赚钱的故事
- Codeforces Round #613 (Div. 2) E. Delete a Segment 离散化
- 很全的路由器默认初始密码集合.txt_UpSet——集合关系可视化神器
- 谈一谈Java编程开发中虚拟机的内存区域划分?猿们怎么看?
- python画布位置_如何调整tkinter画布的位置
- 最大流算法(Edmons-Karp + Dinic 比较) + Ford-Fulkson 简要证明
- 路遥《平凡的世界》读后感
- 微信小程序金额千分位
- SpringBoot整合MybatisPlus实现逻辑删除
- MATLAB与信号处理课程手册
- 【搜索/提问必备】如何正确的在Stack Overflow提问
- 全球与中国家用手动和电动工具的产能、产量、销量、销售额、价格及未来趋势
- 闲鱼商品选投实时性优化
- artdialog ajax新增,artDialog 对话框组件使用简介
- 数字图像处理--冈萨雷斯第4版--第一章 绪论
- 基于threejs的商品VR展示平台的设计与实现思路
- 【JS】Proxy(代理)
- 2021年企业服务行业BP和融资计划书PPT模板
热门文章
- 超越 EfficientNet!小米AutoML 团队开源 Scarlet 模型!
- 是时候学习生成对抗网络了,李宏毅老师GAN视频教程下载
- mysql 实现非递归树_二叉树的非递归前序,中序,后序遍历算法
- Python编辑统一缩进(Pycharm)
- enum java 比较_Kotlin与Java比较:枚举类
- CNN卷积神经网络分析
- 算法移植优化(六)tensorflow模型移植推理优化
- Ubuntu16.04+Cuda8.0+cuDNN6配置py-faster rcnn(转)
- linux的可执行文件通常放在哪个目录中?写出该目录的路径.,实验2 Linux的基本操作与 使用vi编辑器 2010 (1)...
- 我有一个域名_一个域名可以绑定几个网站?域名解析多少子域名?