图形绘制方面我觉得HenCoder系列是比较透彻易懂的,非常推荐,所以正在学习他的一系列文章
以下是我的笔记
原文链接:
HenCoder Android 开发进阶:自定义 View 1-3 文字的绘制
Android 开发进阶:自定义 View 1-4 Canvas 对绘制的辅助
Android 开发进阶:自定义 View 1-5 绘制顺序
1.文字绘制
1.Canvas 的文字绘制方法有三个:
drawText() 常用方法
drawTextRun() 不常用,对于一些特殊国家文字管用
drawTextOnPath()按照一定的路径绘制文字
2.StaticLayout
drawText不能自动换行也不会对换行符起作用,StaticLayout 支持换行,它既可以为文字设置宽度上限来让文字自动换行,也会在 \n 处主动换行。
并不是一个 View 或者 ViewGroup ,而是 android.text.Layout 的子类,它是纯粹用来绘制文字的
3.测量文字的方法
1.getTextBounds(String text, int start, int end, Rect bounds)
text 是要测量的文字,start 和 end 分别是文字的起始和结束位置,bounds 是存储文字显示范围的对象,方法在测算完成之后会把结果写进 bounds
它测量的是文字的显示范围(关键词:显示)。形象点来说,你这段文字外放置一个可变的矩形,然后把矩形尽可能地缩小,一直小到这个矩形恰好紧紧包裹住文字,那么这个矩形的范围,就是这段文字的 bounds
2.float measureText(String text)
测量文字的宽度并返回,它测量的是文字绘制时所占用的宽度(关键词:占用)
由于左右要加上一些字间距,所以用这个方法测量出来的比用getTextBounds要大
3.getTextWidths(String text, float[] widths)
获取字符串中每个字符的宽度,并把结果填入参数 widths。
4.int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth)
在给出宽度上限的前提下测量文字的宽度。如果文字的宽度超出了上限,那么在临近超限的位置截断文字
返回值是截取的文字个数(如果宽度没有超限,则是文字的总个数)
这个方法可以用于多行文字的折行计算
2.Canvas
1.范围裁切
clipRect()
clipPath()
裁切方法之后的绘制代码,都会被限制在裁切范围内。要加上 Canvas.save() 和 Canvas.restore() 来及时恢复绘制范围
2.几何变换
2.1使用 Canvas 来做常见的二维变换;
Canvas.translate(float dx, float dy) 平移
Canvas.rotate(float degrees, float px, float py) 旋转
Canvas.scale(float sx, float sy, float px, float py) 放缩
skew(float sx, float sy) 错切
需要注意的是这几个方法都是preconcat,所以需要把变换顺序反着写,比如:先平移在旋转,那代码就要先写旋转再写平移。
2.2使用 Matrix 来做常见和不常见的二维变换;
创建 Matrix 对象;
调用 Matrix 的 pre/postTranslate/Rotate/Scale/Skew() 方法来设置几何变换;
使用 Canvas.setMatrix(matrix) 或 Canvas.concat(matrix) 来把几何变换应用到 Canvas。这两者区别是前者用 Matrix 直接替换 Canvas 当前的变换矩阵,即抛弃 Canvas 当前的变换,不同的手机系统中 setMatrix(matrix) 的行为可能不一致,后者用 Canvas 当前的变换矩阵和 Matrix 相乘,即基于 Canvas 当前的变换,叠加上 Matrix 中的变换,尽量用后者
2.3使用 Camera 来做三维变换。
Camera 的三维变换有三类:旋转、平移、移动相机。
Camera 和 Canvas 一样也需要保存和恢复状态才能正常绘制
3.绘制顺序
在 ViewGroup 的子类中重写除 dispatchDraw() 以外的绘制方法时,可能需要调用 setWillNotDraw(false);
在重写的方法有多个选择时,优先选择 onDraw()。