美文网首页
图形的位置测量和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(一)

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