博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
6.4 Android绘图技巧(Primary:四大方法&Layer)
阅读量:6954 次
发布时间:2019-06-27

本文共 5504 字,大约阅读时间需要 18 分钟。

1.Canvas的四大金刚

  • Canvas.save()

    这个方法从字面上可以理解为保存画布,作用就是将之前的所有已绘制的图像保存起来。让后续的操作就好像在一个新的图层上操作一样,这一点与Photoshop中的图层理解基本一致。

  • Canvas.restore()

    可以理解为Photoshop中的合并图层操作,作用是将我们在save()之后绘制的所有图像与save()之前的图像进行合并。

  • Canvas.translate()

    Android默认绘图坐标零点位于屏幕左上角,那么在调用translate()之后,则将零点(0,0)移动到了(x,y)。之后所有绘图操作都将以(x,y)为原点执行。

  • Canvas.rotate()

    与translate()同理,旋转坐标系一个一定的角度。

2.Demo:仪表盘

2.1.画外圆

img_5aaab685169101624d3e067fbc9607ab.png

2.2.画刻度和刻度值

img_2db34fe064a6a295afd906160249201f.png

2.3.画指针

img_8223877616dc227d7bdf8b6cac7230e7.png

2.4.全代码和运行结果

Clock.java:

package com.yishengxu.myapplication;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;public class Clock extends View {    private int mHeight, mWidth;    public Clock(Context context) {        super(context);    }    public Clock(Context context, AttributeSet attrs) {        super(context, attrs);    }    public Clock(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onDraw(Canvas canvas) {        // 获取宽高参数        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();        // 画外圆        Paint paintCircle = new Paint();        paintCircle.setStyle(Paint.Style.STROKE);        paintCircle.setAntiAlias(true);        paintCircle.setStrokeWidth(5);        canvas.drawCircle(mWidth / 2,                mHeight / 2, mWidth / 2, paintCircle);        // 画刻度        Paint painDegree = new Paint();        paintCircle.setStrokeWidth(3);        for (int i = 0; i < 24; i++) {            // 区分整点与非整点            if (i == 0 || i == 6 || i == 12 || i == 18) {                painDegree.setStrokeWidth(5);                painDegree.setTextSize(30);                canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2,//基线起点x                        mWidth / 2, mHeight / 2 - mWidth / 2 + 60,//基线起点y                        painDegree);                String degree = String.valueOf(i);//Integer.toString(i)                canvas.drawText(degree,                        mWidth / 2 - painDegree.measureText(degree) / 2,//measureText()在画布上输出文本之前,检查字体的宽度:                        mHeight / 2 - mWidth / 2 + 90,                        painDegree);            } else {                painDegree.setStrokeWidth(3);                painDegree.setTextSize(15);                canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2,                        mWidth / 2, mHeight / 2 - mWidth / 2 + 30,                        painDegree);                String degree = String.valueOf(i);                canvas.drawText(degree,                        mWidth / 2 - painDegree.measureText(degree) / 2,                        mHeight / 2 - mWidth / 2 + 60,                        painDegree);            }            // 通过旋转画布简化坐标运算            canvas.rotate(15, mWidth / 2, mHeight / 2);//二三参数为枢轴点的xy,枢轴点即旋转中心        }        // 画圆心        Paint paintPointer = new Paint();        paintPointer.setStrokeWidth(30);        canvas.drawPoint(mWidth / 2, mHeight / 2, paintPointer);        // 画指针        Paint paintHour = new Paint();        paintHour.setStrokeWidth(20);        Paint paintMinute = new Paint();        paintMinute.setStrokeWidth(10);        canvas.save();//只是保存“缓冲区”绘制的内容        canvas.translate(mWidth / 2, mHeight / 2);        canvas.drawLine(0, 0, 100, 100, paintHour);        canvas.drawLine(0, 0, 100, 200, paintMinute);        canvas.restore();//将“缓冲区”绘制的内容和已经save()的内容一同合并并保存起来,这里跟上边的save注意区分开来    }}

MainActivity.java:

package com.yishengxu.myapplication;import android.app.Activity;import android.os.Bundle;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new Clock(this));    }}

效果图:

img_62d0c2660e6db4f224143f94fe628345.png

3.Layer图层

创建一个新的Layer到“栈”中,可以使用saveLayer(), savaLayerAlpha(), 从“栈”中推出一个Layer,可以使用restore(),restoreToCount()。但Layer入栈时,后续的DrawXXX操作都发生在这个Layer上,而Layer退栈时,就会把本层绘制的图像“绘制”到上层或是Canvas上,在复制Layer到Canvas上时,可以指定Layer的透明度

  • 透明度:
  • 127,半透明
  • 255,完全不透明
  • 0,完全透明
    实例如Demo下图:

上Demo:

package com.imooc.myapplication;import android.app.Activity;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new MyLayer(this));    }    public class MyLayer extends View {        private Paint mPaint;        private static final int LAYER_FLAGS =                        Canvas.MATRIX_SAVE_FLAG |                        Canvas.CLIP_SAVE_FLAG |                        Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |                        Canvas.FULL_COLOR_LAYER_SAVE_FLAG |                        Canvas.CLIP_TO_LAYER_SAVE_FLAG;//此乃API定义的常量,ctrl+E 进入文档查看便知晓其含义        public MyLayer(Context context) {            super(context);            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        }        @Override        protected void onDraw(Canvas canvas) {            canvas.drawColor(Color.WHITE);//背景            mPaint.setColor(Color.BLUE);            canvas.drawCircle(150, 150, 100, mPaint);//“零图层”            canvas.saveLayerAlpha(0, 0, 400, 400, 127, LAYER_FLAGS);            mPaint.setColor(Color.RED);            canvas.drawCircle(200, 200, 100, mPaint);            canvas.restore();        }    }}

半透明:

img_59445d8b68b48ba229ac26a234272f04.png

完全不透明: canvas.saveLayerAlpha(0, 0, 400, 400, 255, LAYER_FLAGS);

img_2cfb60d895b733565110d393e7704957.png
image.png

完全透明: canvas.saveLayerAlpha(0, 0, 400, 400, 0, LAYER_FLAGS);

img_2d0a554243a662ab7a2e07872249ed09.png

转载地址:http://ibtil.baihongyu.com/

你可能感兴趣的文章
(转)Java并发编程:并发容器之ConcurrentHashMap
查看>>
java常用英语单词
查看>>
SQLSERVER系统视图,系统表,sys.sql_modules视图
查看>>
DEDECMS之十 修改织梦链和文章的默认来源及作者
查看>>
【转载】C#数据导出到Excel文件
查看>>
转:数字签名是什么?(阮一峰)
查看>>
.NET程序内存分析工具CLRProfiler的使用(性能测试)
查看>>
马克飞象 Markdown 使用和学习
查看>>
Struts2拦截器浅析
查看>>
java 文件上传数据库
查看>>
JAVA设计模式初探之组合模式
查看>>
[LeetCode][Java] Substring with Concatenation of All Words
查看>>
coco定义的小物体中物体大物体的尺寸
查看>>
Spark2.1.0之源码分析——事件总线
查看>>
如何解压.gz的压缩文件
查看>>
UVA 10718 Bit Mask
查看>>
Android核心分析28篇,强烈推荐android初学者,android进阶者看看这个系列教程
查看>>
BCM平台全自动刷机软件,TFTP正式版1.62隆重发布,增加固件记忆功能
查看>>
libvirt API 学习
查看>>
同时支持行单击和双击事件的 GridView/DataGrid
查看>>