为了账号安全,请及时绑定邮箱和手机立即绑定

自定义View合辑(7)-带文本的球形波浪(贝塞尔曲线)

为了加强对自定义 View 的认知以及开发能力,我计划这段时间陆续来完成几个难度从易到难的自定义 View,并简单的写几篇博客来进行介绍,所有的代码也都会开源,也希望读者能给个 star 哈
GitHub 地址:https://github.com/leavesC/CustomView
也可以下载 Apk 来体验下:https://www.pgyer.com/CustomView

先看下效果图:

WaveLoadingView 和上一节的 WaveView 类似,但比之多了一个颜色随波浪起伏而变化的文本,且形状也变为了圆形。此处波浪的绘制思路与上一节一样,重点就在于文本的绘制顺序以及画布的裁切

绘制流程分为以下几步:

  • 绘制颜色为 A 的文本
  • 按照上一节 WaveView 的步骤,绘制具备波浪轨迹的 wavePath
  • 绘制形状为圆形的 circlePath
  • 将 wavePath 和 circlePath 的相交轨迹赋予 circlePath(通过 op 函数实现,此时就已经得到圆形的波浪轨迹了)
  • 将 circlePath 实际绘制到 Canvas 上
  • 对 Canvas 依据轨迹 circlePath 进行裁切
  • 绘制颜色为 B 的文本
    private Path circlePath = new Path();

    private Path wavePath = new Path();

    @Override
    protected void onDraw(Canvas canvas) {
        textPaint.setColor(waveColor);
        drawText(canvas, textPaint, String.valueOf(text));

        wavePath.reset();
        wavePath.moveTo(-waveWidth + animatedValue, size / 2.2f);
        for (float i = -waveWidth; i < size + waveWidth; i += waveWidth) {
            wavePath.rQuadTo(waveWidth / 4, -waveHeight, waveWidth / 2, 0);
            wavePath.rQuadTo(waveWidth / 4, waveHeight, waveWidth / 2, 0);
        }
        wavePath.lineTo(size, size);
        wavePath.lineTo(0, size);
        wavePath.close();

        circlePath.reset();
        circlePath.addCircle(centerX, centerY, radius - 1, Path.Direction.CCW);
        circlePath.op(wavePath, Path.Op.INTERSECT);

        canvas.drawPath(circlePath, wavePaint);
        canvas.clipPath(circlePath);

        textPaint.setColor(downTextColor);
        drawText(canvas, textPaint, String.valueOf(text));
    }

    private void drawText(Canvas canvas, Paint textPaint, String text) {
        Rect rect = new Rect(0, 0, size, size);
        textPaint.setTextAlign(Paint.Align.CENTER);
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float top = fontMetrics.top;
        float bottom = fontMetrics.bottom;
        int centerY = (int) (rect.centerY() - top / 2 - bottom / 2);
        canvas.drawText(text, rect.centerX(), centerY, textPaint);
    }
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消