自定义View 之 Path应用

因为项目需要需要做几个自定义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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值