美文网首页
图形的位置测量和xfermode的使用-自定义view(一)

图形的位置测量和xfermode的使用-自定义view(一)

作者: 程序猿峰岑 | 来源:发表于2019-12-10 14:52 被阅读0次

图形绘制的基本要素:
1.onDraw(Canvas) --- 所有的尺寸都是像素
2.Canvas
3.Paint
4.坐标系
5.尺寸单位

onDraw绘图api
1.drawColor() ----------- 画颜色
2.drawLine() ----------- 画线
3.drawRect() ----------- 画矩形
4.drawRoundRect() ----- 画带有圆角的矩形
5.drawCircle() ---------- 画圈
6.drawOval(). ----------- 画圆
7.drawArc() ---------- 画弧
8.drawPaint() ---------- 画笔
9.DrawPath() ---------- 画轨迹
10.drawBitmap -------- 画图像
11.drawText() --------- 画文本

Path. ------ api

addxxx().
moveTo().
xxxTo()
PathMeasure().
setFillType()

画线

[图片上传中...(image.png-900126-1575875471719-0)]

画圆

image.png

onSizeChanged方法

这个方法是在onMeasure方法后调用,如果测量的结果不一样,这个方法会被调用。

Path画圆

path.addCircle(getWidth()/2,getHeight()/2,RADIUS, Path.Direction.CCW)

我讲下第四个参数,
Path.Direction.CW表示的是顺时针,Path.Direction.CCW逆时针
它的作用是多个图形的填充规则
为了更好的了解上面的参数,我们在画一个矩形
矩形图形代码:

path.addRect(getWidth()/2-RADIUS,getHeight()/2,getWidth()/2+RADIUS,getHeight()/2+RADIUS*2,Path.Direction.CCW);

图形如下:


image.png

现在我们再把矩形的CCW改为CW,又会是怎样的效果呢?


image.png
还有种方法是通过api path.setFillType()来填充
它有四种状态 分别是EVEN_ODD,INVAESE_EVEN_ODD,INVERSE_WINDING,WINDING

它们分别表示奇数填充,奇数反方向填充也就是偶数。包含取反填充和包含填充,后面两种应该很好理解,前面两种就不是那么好理解了。
其实他在绘制图形的时候是有一定的规则的,也就是如果是逆时针记为1。顺时针记为-1 相交处累加。图形解释如下:


image.png
我们在画一个比较大的圆。代码如下:
path.addCircle(getWidth()/2,getHeight()/2,RADIUS*2,Path.Direction.CCW);

运行结果如下:


image.png

自定义仪表盘

1.定义DashBoardView继承View
2.初始化画笔Paint

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

 private void init(){
        paint.setStrokeWidth(4);
        paint.setStyle(Paint.Style.STROKE);
    }

3.定义圆弧的大小以及劣弧的角度

 private static final int RADIUS = DisplayUtils.dpToPx(150);
    private static final int ANGLE = 120;

4.onDraw()方法使用canvas.drawArc

canvas.drawArc(getWidth()/2-RADIUS,getHeight()/2-RADIUS,
                getWidth()/2+RADIUS,getHeight()/2+RADIUS,90+ANGLE/2,
                360-ANGLE,false,paint);

先试下效果:


image.png

弧线画好了,接下来我们在画下刻度

1.实例化 Path dash = new Path()
2.定义刻度大小

dash.addRect(0,0,DisplayUtils.dpToPx(2),DisplayUtils.dpToPx(10), Path.Direction.CCW);

3.画刻度:
pathMeasure的作用就是计算轨迹的长度,我这里是画20刻度,这里就是用的轨迹长度减去刻度的宽度除以20 得到刻度之间的间隔宽度。

path.addArc(getWidth()/2-RADIUS,getHeight()/2-RADIUS,
                getWidth()/2+RADIUS,getHeight()/2+RADIUS,90+ANGLE/2,
                360-ANGLE);
        pathMeasure = new PathMeasure();
        pathMeasure.setPath(path,false);
        pathDashPathEffect = new PathDashPathEffect(dash,(pathMeasure.getLength()-DisplayUtils.dpToPx(2))/20,0, PathDashPathEffect.Style.ROTATE);

刻度这里就算画好了 接下来我们画指针
先设置指针长度:private static final int LENTH = DisplayUtils.dpToPx(100)
此处用到了正余弦相关的知识Math.cos()填入的内容为弧度,这里我们需要把角度转换为弧度Math.toRadians()

canvas.drawLine(getWidth()/2,getHeight()/2,
                getWidth()/2+(float)Math.cos(Math.toRadians(getAngleForMark(5)))*LENTH,
                getHeight()/2 + (float)Math.sin(Math.toRadians(getAngleForMark(5)))*LENTH,paint);

角度:

private float getAngleForMark(int mark){
        return 90 + ANGLE/2 + (360 - ANGLE)/20 * mark;
    }

效果图:


image.png

xfermode的使用

我这里使用xfermode做了一个头像的剪裁,核心代码如下:

Xfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);

canvas.drawOval(border,paint);
        int saveCount = canvas.saveLayer(cut,paint);
        canvas.drawOval(cut,paint);
        paint.setXfermode(xfermode);
        canvas.drawBitmap(avatar,PADDING,PADDING,paint);
        paint.setXfermode(null);
        canvas.restoreToCount(saveCount);

对于xfermode我们主要关注的就是选择的mode-PorterDuff.Mode.xxx
而对于选择的mode,那么我们就要对不同的mode它们的作用有所了解,为了了解这个mode,我们可以从developers中寻找答案:
原始图形:


image.png

选择不同mode的图形如下:

ADD

image.png

CLEAR

image.png

DARKEN

image.png

DST

image.png

DST_ATOP

image.png

DST_IN

image.png

DST_OUT

image.png

DST_OVER

image.png

LIGHTEN

image.png

MULTIPLY

image.png

OVERLAY

image.png

SCREEN

image.png

SRC


image.png

SRC_ATOP

image.png

SRC_IN

image.png

SRC_OUT

image.png

SRC_OVER

image.png

XOR

image.png

其实这些view还是有些粗糙的,今后有时间把仪表盘做成指南针或者速度仪。自定义头像可以做成项目中灵活引用可以自己设置参数,还有一个东西没讲到就是饼状图。我已经把这些自定义的东西已经上传到了github
源码

相关文章

  • 图形的位置测量和xfermode的使用-自定义view(一)

    图形绘制的基本要素:1.onDraw(Canvas) --- 所有的尺寸都是像素2.Canvas3.Paint4....

  • 自定义View基础概述

    1.自定义View的基本方法 onMeasure():测量视图大小 onLayout():确定View位置,进行页...

  • 自定义TagView

    自定义viewGroup的重点是如何测量子view,并根据自己的规则去计算子view的位置和尺寸本文通过在TagV...

  • Android控件测量-MesaureSpec详解

    1.View的测量 如果我们想要在界面上画一个图形,那么必须要先知道控件的大小和位置。所以系统在绘制View之前,...

  • 【Android】自定义View那点事(三)ColorFilte

    前言 前面学习Xfermode的使用,我们可以自定义各种不同样式的View,本节我们学习关于颜色处理相关的内容。现...

  • 自定义控件

    1.自定义控件方法的理解 (1) View的测量onMeasure():这个方法主要是测量View宽度和高度。 在...

  • 2019-12-23

    自定义view画渐变图形,inflate 自定义view:画渐变图形 参考:自定义View-第十六步:Linear...

  • 自定义View

    自定义View 一、 View的绘制流程 onMeasure() --测量View的大小onLayout()-- ...

  • Android控件架构与自定义控件(二)

    View的测量: 在现实生活中,如果我们要去画一个图形,就必须知道他的大小和位置。同样Android系统在绘制Vi...

  • 自定义ViewGroup—回顾

    自定ViewGroup要比自定义View要复杂一点,因为自定义ViewGroup不仅测量自身还要测量子元素和及重写...

网友评论

      本文标题:图形的位置测量和xfermode的使用-自定义view(一)

      本文链接:https://www.haomeiwen.com/subject/yjibgctx.html