## 前言

每次在讲正事前总要啰嗦几句,其实我也不想,只是文章没得一个开头,看起来就有点不爽,所以大家见谅,不喜欢的可以直接跳过。Android的绘图功能还是十分强大的,只要你有一个敢于创新的心,就没有什么画不出来的,接下来我将,从画图时所使用的工具开始介绍,希望能够帮助到大家,我自己也能够更好的巩固这方面的知识。

绘图工具(一)–画布(canvas)

canvas类相当于一个画布,我们通常把它理解成系统提供给我们的一块内存区(但实际上它只是一套画图的API),并且提供了一套在这个区域操作的一系列方法,着些方法全是用来画图API

以下是canvas常用画图的方法:

  • drawRect(RectF rect, Paint paint) //绘制区域,参数一为RectF一个区域

  • drawPath(Path path, Paint paint) //绘制一个路径,参数一为Path路径对象

  • drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //贴图,参数一就是我们常规的Bitmap对象,参数二是源区域(这里是bitmap),参数三是目标区域(应该在canvas的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。

  • drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) //画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint 画刷对象。

  • drawPoint(float x, float y, Paint paint) //画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。

  • drawText(String text, float x, floa ty, Paint paint) //渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。

  • drawOval(RectF oval, Paint paint)//画椭圆,参数一是扫描区域,参数二为paint对象;

  • drawCircle(float cx, float cy, float radius,Paint paint)// 绘制圆,参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是paint对象;

  • drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//画弧,参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始,参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,如果它是假这将是一个弧线,参数五是Paint对象;

除此以外还有一些方法特别有用:

  • Canvas.save() 将之前所有已经绘制的图像保存起来,让后续的操作好像在一个新的图层中操作一样

  • Canvas.restore() 该方法可以理解为PS中的合并图层操作,作用是将save()之前后的图像进行合并

  • Canvas.translate(x,y) 该方法的意思是将坐标系的原点移动到(x,y) 处,之后所有的操作都将以(x,y)为原点进行

  • Canvas.rotate() 将坐标系选装一定的角度

绘图工具(二)–画笔(Paint)

系统通过Canvas对象来提供绘图方法,但是还缺少一个绘图的笔来完成整个绘图的操作。可以看到Canvas的很多方法的最后都需要传入一个Paint对象,由此可见Paint画笔的重要性,Paint对象在画图中主要起到对线条颜色,效果,风格的控制上。接下来是一些常用的Paint的属性和对应功能。

  • setAntiAlias(); 设置画笔的锯齿效果

  • setColor(); 设置画笔的颜色

  • setARGB(); 设置画笔的A , R , G , B值

  • setAlpha(); 设置画笔的Alpha值(透明度 取值0~255之间,越小透明度越高)

  • setTextSize(); 设置字体的尺寸(有时在绘图中也需要绘画字体)

  • setStyle(); 设置画笔的风格(空心或者实心)

  • setStrokeWidth(); 设置画笔的宽度

绘图工具(三)–路径(Path)

path类用于记录一些路径,可以当作是看不见的线,也可以用作记录手指接触屏幕滑动的路径,绘制复杂图形轮廓等等,在绘图和动画中,path类都发挥着重要的作用。

构造方法:
创建一个含有src的path对象(目前还没有用过)

    public Path(Path src) {        long valNative = 0;        if (src != null) {            valNative = src.mNativePath;            isSimplePath = src.isSimplePath;            if (src.rects != null) {                rects = new Region(src.rects);            }        }        mNativePath = init2(valNative);    }

接下来列举一些常用的方法

  • moveTo(float x , float y) 移动绘制起点到(x,y)的位置开始绘制

  • lineTo(float x , float y) 连接从起点到(x,y)的直线,默认起点为(0,0)

  • rMoveTo(float dx, float dy) 在上一次绘制的终点的基础上,移动dx,dy的距离得到新的起点。(这里的dx , dy为移动的距离)

  • rLineTo(float dx , float dy)在上一次绘制的基础上,移动dx , dy的连线。和lineTo()的效果一样,只是起点是上一次绘制的终点,坐标表示的是距离。

  • quadTo(float x1 , float y1 , float x2 , float y2) 根据两个点你控制,绘制贝塞尔曲线

  • cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)根据三点控制,绘制贝尔塞曲线

  • arcTo(RectF oval, float startAngle, float sweepAngle)用于绘制圆弧

  • addRect(float left, float top, float right, float bottom, Direction dir)添加矩形

  • addOval(RectF oval, Direction dir) 添加一个闭环圆环路径

  • addCircle(float x, float y, float radius, Direction dir) 添加一个圆形路径

  • addRoundRect(RectF rect, float rx, float ry, Direction dir)添加一个圆角矩形路径

  • offset(float dx, float dy, Path dst) 通过dx,dy移动路径,如图dst为null则修改原路径,即src

  • reset() 清空当前路径中的设置信息

  • rewind() 清空当前path,清空所有的直线曲线,但保留其数据结构,方便重用

注:
Path.Direction 用来指定添加到path中的闭合图形的绘制方向(两个值,分别为顺时和逆时)

  • CW 表示顺时针

  • CCW表示逆时针

FillType表示填充模式:

  • FillType.WINDING 默认值,当两个图形香蕉,正常相交情况显示

  • FillType.EVEN_ODD 取path所在并不相交的区域

  • FillType.INVERSE_WINDING 取path的外部区域

  • FillType.INVERSE_EVEN_ODD 取path外部和相交区域

(INVERSE就是取反的意思)下面是几个填充结果

FillType.WINDING

FillType.EVEN_ODD

FillType.INVERSE_WINDING

INVERSE_EVEN_ODD

接下来通过一个实例来巩固一下这个绘制的内容。我们要做的是一个时钟的图形,如下图:

首先分析这个图形所需要绘制的元素有:表盘,刻度,指针,数字

首先我们选择绘制表盘,表盘就是一个大圆盘,直接调用canvas.drawCircle()方法绘制一个圆就行了,关键是定圆心和半径,这里直接确定在屏幕中间了

        private Paint paintCircle;        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();//获取屏幕宽高        paintCircle = new Paint();//初始化画笔        paintCircle.setColor(Color.BLACK);//设置颜色        paintCircle.setAntiAlias(true);        paintCircle.setStyle(Paint.Style.STROKE);        paintCircle.setStrokeWidth(5);//设置笔宽        canvas.drawCircle(mWidth/2 , mHeight/2 , mWidth/2 , paintCircle);//画圆

完成了表盘后就开始画刻度线,这个也不难就是一条线段,只要确定了两端点的坐标就可以轻松搞定,关键问题是斜着的线段如何获取坐标呢,这里利用到了旋转坐标系,看如下代码:

        paintDegree = new Paint();        paintCircle.setStrokeWidth(3);        for(int i = 0 ; i < 24 ; i++){            if(i == 0 || i == 6 || i == 12 || i == 18){//正的时刻直接画出                paintDegree.setStrokeWidth(5);                paintDegree.setTextSize(30);                canvas.drawLine(mWidth/2, mHeight/2 - mWidth/2,mWidth/2,mHeight/2 - mWidth/2 +60,paintDegree );                String degree = String.valueOf(i);                canvas.drawText(degree,mWidth/2 - paintDegree.measureText(degree)/2, mHeight/2 - mWidth/2 + 90,paintDegree);            }else{//斜着的时刻绘制                paintDegree.setStrokeWidth(3);                paintDegree.setTextSize(15);                canvas.drawLine(mWidth/2, mHeight/2 - mWidth/2,mWidth/2,mHeight/2 - mWidth/2 +60,paintDegree);                String degree = String.valueOf(i);                canvas.drawText(degree,mWidth/2 - paintDegree.measureText(degree)/2, mHeight/2 - mWidth/2 + 90,paintDegree);            }            canvas.rotate(15 ,mWidth/2 , mHeight/2);//旋转坐标系        }

最后绘制时针,计时从原点开始的两条线段

        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();//组合画布

到此为止就完成了整个绘画的过程,当然其中没有用到path,不过不要紧,在后续的动画讲解中,path会有很多作用的,还有前面有一篇介绍SurfaceView使用的文章中,就有使用path来记录手指在屏幕滑动的轨迹。绘图机制中的绘制就到此结束了,当然还有3D的绘图,我自己还在学习当中~希望这篇文章能够帮助到大家~我们一起加油~

更多相关文章

  1. Android自动手绘,圆你儿时画家梦!
  2. android TextView 显示不全的问题解决,此问题是设置了maxLines和e
  3. Android(安卓)post请求时参数上传失败
  4. Android(安卓)进阶 APP优化 包体积优化
  5. android画笔移位解决
  6. android跳转小程序并返回遇到的坑点和解决方案
  7. 利用Canvas实现在屏幕随机位置绘制10个大小(边长为10-160)颜色随
  8. android APP性能优化总结
  9. Android(安卓)进阶第二篇——性能优化

随机推荐

  1. android学习——GridView实现主界面布局
  2. Flutter 配置打包
  3. Android(安卓)面试必问高级知识点(2021)
  4. Android侧滑菜单DrawerLayout的使用
  5. Android启动画面实现
  6. Android(安卓)Apk打包的流程
  7. android开发之Android(安卓)ActionBar完
  8. android自定义按钮控件样式
  9. Android(安卓)基础知识介绍
  10. Android基于ViewFilpper实现文字LED显示