自定义View 之 Path应用

来源:互联网 发布:think php 编辑:程序博客网 时间:2024/05/21 11:13
因为项目需要需要做几个自定义View,用到了Path,所以在结束后,总结分享下。

先看看效果吧。

这里写图片描述

大概就是一个防太阳运转的一个自定义view,还有一个是不规则曲线的进度条。

补充(2017-4-27)最终效果图

这里写图片描述

原理

SunProgressBar 找一个中心点画一个半圆,然后再创建一个矩形的Path路径,使用Path的op()方法,然后用刚刚的半圆路径限制矩形路径,动态的绘制矩形大小,取共集,就做出了这个效果了。
@RequiresApi(api = Build.VERSION_CODES.KITKAT)    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawLine(canvas);        drawFilter(canvas);        drawProgressLogo(canvas);    }//绘制中间填充的粉红色的部分@RequiresApi(api = Build.VERSION_CODES.KITKAT)    private void drawFilter(Canvas canvas) {//        mFilterRectF.right = (int) (mProgress * (mRectF.right - mRectF.left));        mFilterRectF.right = mProgressPoint.x;        Log.e("wwwww", "wwww" + mFilterRectF.right);        Path circlePath = new Path();        circlePath.addCircle(mCenterPoint.x, mCenterPoint.y, mRadius - bitmapPadding, Path.Direction.CW);        Path squrePath = new Path();        squrePath.addRect(mFilterRectF, Path.Direction.CW);        squrePath.op(circlePath, Path.Op.INTERSECT);        canvas.drawPath(squrePath, mFilterPaint);    }

LineProgress 给出一系列的不规则点,然后绘制一条灰色的贝塞尔曲线作为背景,然后再用PathMeasure 截取背景Path的部分长度,绘制进度条,随着进度的不断变化,然后截取的长度也在变化,就做出了一个动画

@RequiresApi(api = Build.VERSION_CODES.KITKAT)    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawLine(canvas);    }    @RequiresApi(api = Build.VERSION_CODES.KITKAT)    private void drawLine(Canvas canvas) {        Path path = new Path();        Path line2 = new Path();        final float point_unit_width = mMainRectF.right / mPoint_h.length;        for (int i = 0; i < mPoint_h.length - 1; i++) {            final int startX = (int) (i * point_unit_width);            final int startY = (int) (mMainRectF.bottom * mPoint_h[i]);            final int endX = (int) ((i + 1) * point_unit_width);            final int endY = (int) (mMainRectF.bottom * mPoint_h[i + 1]);            int wt = (startX + endX) / 2;            Point p3 = new Point();            Point p4 = new Point();            p3.y = startY;            p3.x = wt;            p4.y = endY;            p4.x = wt;            if (i == 0) {                path.moveTo(startX, startY);                line2.moveTo(startX, startY);            }            if (i == mPoint_h.length - 1)                line2.lineTo(endX, endY);            path.cubicTo(p3.x, p3.y, p4.x, p4.y, endX, endY);        }        canvas.drawPath(path, mBgPaint);        Path dst = new Path();                                      // 创建用于存储截取后内容的 Path        PathMeasure measure = new PathMeasure(path, false);        float stopD = measure.getLength() * mProgress;        float[] pos = new float[2];        float[] tan = new float[2];        measure.getPosTan(stopD, pos, tan);        measure.getSegment(0, stopD, dst, true);        canvas.drawPath(dst, mProgressPaint);        canvas.drawCircle(pos[0], pos[1], mLineWidth * 2, mProgressPaint);    }

OK,关键性的就写完了,如果大家感兴趣,可以下载我的Demo看看,因为我电脑的PS给卸载了,录屏转化不了了,所以LineProgress 给大家预览不了,后期我会补上的。

下面附上github连接地址,有需要的同学可以下载玩玩,代码及其简单,大家可以自己修改修改

https://github.com/LittlEyes/SunMoveView

0 0