这一节主要复习Android里的Paint使用,先了解一些绘制相关的背景知识。
硬件加速
GPU 的英文全称为 Graphic Processing Unit,中文翻译为“图形处理器”。 与 CPU 不同 ,GPU 是专门为处理图形任务而产生的芯片 。在 GPU 出现之前, CPU 一直负责所有的运算工作。 CPU 的架构是有利于 X86 指令集的串行架构, CPU 从设计思路上适合尽可能快地完成一项任务,但当面对类似多媒体、图形图像处理类型的任务时,就会显得力不从心 。 因为在多媒体计算中通常要求更高的运算密度、多并发线程和频繁的存储器访问 。 显然,当你打游戏时,屏幕上的动画是需要实时刷新的,这些都需要频繁的计算、存取动作 。 如果CPU不能及时响应,屏幕就会显得很卡。为了专 门处理多媒体的计算,存储任务, GPU 应运而生。 GPU 中自带处理器和存储器,专 门用来计算和存储多媒体任务 。
软件绘制与硬件加速的区别:
在 CPU 绘制和 GPU 绘制时,在流程上是有区别的 。在基于软件的绘制模型下, CPU 主导绘图,视图按照两个步骤绘制 :1 让 View 层次结构失效 。2 绘制 View 层次结构。在基于硬件加速的绘制模式下, GPU 主导绘图,视图按照三个步骤绘制:1让 View 层次结构失效。2 记录、更新显示列表。3 绘制显示列表 。可以发现 ,在 GPU 加速时,流程中 多了一项“记录 、 更新显示列表”, 表示在第一步 View层次结构失效后 ,并不是直接开始逐层绘制 的,而是首先把这些 View的绘制函数作为绘制指令记录在一个显示列表中,然后再读取显示列表中的绘制指令,调用OpenGL 的相关函数完成实际绘制。也就是说, 在 GPU 加速时, 实际上是使用 OpenGL 的相关函数来完成绘制的 。所以,使用 GPU 加速的优点显而易见:硬件加速提高了 Android 系统显示和刷新的速度。它的缺点也显而易见 :1) 兼容性问题 。由于是将绘制函数转换成 OpenGL 指令来绘制的,所以必然会存在OpenGL 并不能完全支持原始绘制函数的问题,从而造成在打开 GPU 加速时效果会失效的问题 。2)电量消耗问题 。多使用了一个部件,当然会更耗电。
Paint
这是Android系统提供的API,该类保存了绘制几何图形、文本和位图的样式和颜色信息。可以使用Paint保存的样式和颜色,来绘制图形、文本和bitmap.
API:
- reset()
- 重置画笔 。
- setColor(int color)
- 给画笔设置颜色值。
- setARGB (int a ,int r ,int g,int b )
- 同样是设置颜色,但是利用 A,R,G,B分开设置 。
- setAlpha(int a)
- 设置画笔透明度 。
- setStyle(Paint.Style style)
- 设置画笔样式,取值如下。
- Paint.Style.FILL:填充内部。
- Paint.Style.FILL_AND_STRO阻:填充内部和描边。
- Paint.Style.STROKE:仅描边 。
- setStrokeWidth(float width)//设置画笔的宽度
- setStrokeCap //设置线帽
- public enum Cap {
- BUTT (0),
- ROUND (1),
- SQUARE (2);
- private Cap(int nativeInt){
- this.nativeInt = nativeInt;
- }
- final int nativeInt;
- }
-
- BUTT:没有线帽,默认模式
- ROUND:圆形
- SQUARE:方形
基本使用
- public class PaintView extends View {
-
- private Paint mPaint;
- private String text = "";
-
- public PaintView(Context context) {
- this(context,null);
- }
-
- public PaintView(Context context, @Nullable AttributeSet attrs) {
- this(context,attrs,0);
- }
-
- public PaintView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context,attrs,defStyleAttr);
- }
-
- private void init(Context context,AttributeSet attrs,int defStyleAttr) {
- mPaint = new Paint();
- mPaint.setTextSize(38);
- mPaint.setColor(Color.RED);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- int x = getPaddingLeft();
- Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
- int dy = (fontMetricsInt.bottom - fontMetricsInt.top)/2 - fontMetricsInt.bottom;
- int baseLine = getHeight()/2 + dy;
- canvas.drawText("HelloWorld...",x,baseLine,mPaint);
- }
- }
- /**
- * text : 要绘制的文字
- * x : 绘制原点 x 坐标
- * y : 绘制原点 y 坐标
- * paint : 用来作画的画笔
- */
- public android drawText (String text, float x, float y, Paint paint )
FontMetrics
我们知道,基线的位置是在构造 drawText()函数时由参数 y 来决定的,那 ascent 、 descent 、top 、 bottom 这些线的位置应该怎么计算出来呢?Android 给我们提供了 一个类 : FontMetrics,它里面有 4 个成员变量。
- FontMetrics: :ascent;
- FontMetrics: :descent;
- FontMetrics: :top;
- FontMetrics: :bottom;
这 4 个成员变量的含义与值的计算方法分别如下:
- ascent = ascent线的y坐标- baseline线的y坐标。
- descent = descent线的y坐标-baseline线的y坐标。
- top= top 线的y坐标-baseline线的y坐标。
- bottom = bottom线的y坐标-baseline线的y坐标。
获取 FontMetrics 对象:
一般根据 Paint 对象来获取 FontMetrics 对象。
- Paint paint = new Paint () ;
- Paint.FontMetrics fm = paint.getFontMetrics();
- Paint.FontMetricsint fmint = paint.getFontMetricsint();
可以看到,通过 paint.getFontMetrics()函数可以得到对应的 FontMetrics 对象 。这里还有一个与 FontMetrics同样的类,叫作 FontMetricslnt,它的含义与FontMetrics 完全相同,只是得到的值的类型不一样而己 。FontMetricslnt 中 4 个成员变量的值都是 Int 类型的,而FontMetricslnt 中 4 个成员变量的值则都是Float类型的 。