iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android自定义View绘制贝塞尔曲线实现流程
  • 573
分享到

Android自定义View绘制贝塞尔曲线实现流程

Android贝塞尔曲线Android贝塞尔曲线实现方法 2022-11-13 19:11:58 573人浏览 安东尼
摘要

目录前言二阶贝塞尔曲线三阶贝塞尔曲线前言 对于Android开发,实现贝塞尔曲线还是比较方便的,有对应的api供你调用。由于一阶贝塞尔曲线就是一条直线,实际没啥多大用处,因此,下面主

前言

对于Android开发,实现贝塞尔曲线还是比较方便的,有对应的api供你调用。由于一阶贝塞尔曲线就是一条直线,实际没啥多大用处,因此,下面主要讲解二阶和三阶。

二阶贝塞尔曲线

在Android中,使用quadTo来实现二阶贝塞尔

        path.reset()
        path.moveTo(startX, startY)
        path.quadTo(currentX, currentY, endX, endY)
        canvas.drawPath(path, curvePaint)

startX和startY,endX和endY为两个固定点,currentX和currentY就是控制点,通过改变控制点的位置来改变二阶贝塞尔曲线的形状。

a点和b点就是固定点,c点是控制点,我们可以改变c点的位置来改变曲线的形状。

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
                currentX = event.x
                currentY = event.y
                postInvalidate()
            }
        }
        return true
    }

三阶贝塞尔曲线

在Android中,使用cubicTo来实现三阶贝塞尔

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        path.reset()
        path.moveTo(startX, startY)
        path.cubicTo(fixedX1, fixedY1, fixedX2, fixedY2, endX, endY)
        canvas.drawPath(path, curvePaint)
        //绘制辅助线
        drawHelpLine(canvas)
    }
    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
                //divideLine区分触摸点是左边还是右边
                if (event.x < divideLine) {
                    fixedX1 = event.x
                    fixedY1 = event.y
                } else {
                    fixedX2 = event.x
                    fixedY2 = event.y
                }
                postInvalidate()
            }
        }
        return true
    }

其中,startX和startY,endX和endY为两个固定点,fixedX1和fixedY1,fixedX2和fixedY2分别为两个控制点,通过改变控制点的位置来改变三阶贝塞尔曲线的形状。

a点和b点就是固定点,c点和d点是控制点,我们可以改变c点或d点的位置来改变曲线的形状。

OK,贝塞尔曲线的基础到此就讲完了,下面来个实战,体验一下贝塞尔曲线的丝滑吧!

关于贝塞尔曲线,最典型的应用就是波浪球了,那咱们也来整一个,先上图

首先裁剪一下画布,变为圆形

        val circlePath = Path()
        circlePath.addCircle(width / 2f, height / 2f, width / 2f, Path.Direction.CW)
        canvas.clipPath(circlePath)

Path.Direction.CW:沿顺时针方向绘制,Path.Direction.CCW:沿逆时针方向绘制

以View为中心,画圆

canvas.drawCircle(width / 2f, height / 2f, width / 2f, circularPaint)

利用二阶贝塞尔,绘制波浪,起点为屏幕外,circleLen为曲线1/4周期长度

private val startPoint = Point(-4 * circleLen, 0)

根据进度改变起点坐标的y值,控制点为曲线的顶部和底部,循环绘制,然后构建曲线之下的封闭区域,填充

        //根据进度改变起点坐标的y值
        startPoint.y = ((1 - (progress / 100.0)) * height).toInt()
        //移动到起点
        wavePath.moveTo(startPoint.x.toFloat(), startPoint.y.toFloat())
        var j = 1
        //循环绘制曲线
        for (i in 1..8) {
            val controlX = (startPoint.x + circleLen * j).toFloat()
            //波顶和波底
            val controlY =
                if (i % 2 == 0) (startPoint.y + waveHeight).toFloat() else (startPoint.y - waveHeight).toFloat()
            //二阶贝塞尔
            wavePath.quadTo(
                controlX,
                controlY,
                (startPoint.x + circleLen * 2 * i).toFloat(),
                startPoint.y.toFloat()
            )
            j += 2
        }
        //绘制封闭的区域
        wavePath.lineTo(width.toFloat(), height.toFloat())
        wavePath.lineTo(startPoint.x.toFloat(), height.toFloat())
        wavePath.lineTo(startPoint.x.toFloat(), startPoint.y.toFloat())
        wavePath.close()
        canvas.drawPath(wavePath, wavePaint)
        wavePath.reset()
        //走完一周回到原点
        startPoint.x =
            if (startPoint.x + translateX >= 0) -circleLen * 4 else startPoint.x + translateX

这里是设置每隔100ms,进度加一

        progress = if (progress >= 100) 0 else progress + 1
        postInvalidateDelayed(100)

全部代码如下

class ProgressBallView : View {
    //曲线1/4周期的长度
    private val circleLen = DensityUtils.dp2px(context, 53)
    //曲线高度
    private val waveHeight = DensityUtils.dp2px(context, 27)
    //默认的长宽值
    private val defaultSize = DensityUtils.dp2px(context, 300)
    //进度
    private var progress = 0
    //平移的长度
    private val translateX = circleLen / 4
    //圆形Paint
    private val circularPaint = Paint()
    //波浪Paint
    private val wavePaint = Paint()
    //波浪的路径
    private val wavePath = Path()
    //曲线的起始坐标
    private val startPoint = Point(-4 * circleLen, 0)
    constructor(context: Context) : super(context)
    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
        initPaint()
    }
    private fun initPaint() {
        with(circularPaint) {
            isAntiAlias = true
            color = Color.GRAY
        }
        with(wavePaint) {
            isAntiAlias = true
            color = Color.RED
        }
    }
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var viewWidth = measureView(widthMeasureSpec)
        var viewHeight = measureView(heightMeasureSpec)
        //取最小的,作为长宽
        viewWidth = min(viewWidth, viewHeight)
        viewHeight = viewWidth
        setMeasuredDimension(viewWidth, viewHeight)
    }
    private fun measureView(measureSpec: Int): Int {
        val mode = MeasureSpec.getMode(measureSpec)
        return if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            MeasureSpec.getSize(measureSpec)
        } else {
            defaultSize
        }
    }
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //裁剪画布为圆形
        cutCanvas(canvas)
        //绘制圆形
        drawRound(canvas)
        //绘制波浪
        drawWave(canvas)
        //自动增长进度
        autoGrow()
    }
    //进度从0-100,自动增长
    private fun autoGrow() {
        progress = if (progress >= 100) 0 else progress + 1
        postInvalidateDelayed(100)
    }
    //裁剪画布为圆形
    private fun cutCanvas(canvas: Canvas) {
        val circlePath = Path()
        circlePath.addCircle(width / 2f, height / 2f, width / 2f, Path.Direction.CW)
        canvas.clipPath(circlePath)
    }
    //绘制圆形
    private fun drawRound(canvas: Canvas) {
        canvas.drawCircle(width / 2f, height / 2f, width / 2f, circularPaint)
    }
    //绘制波浪
    private fun drawWave(canvas: Canvas) {
        //根据进度改变起点坐标的y值
        startPoint.y = ((1 - (progress / 100.0)) * height).toInt()
        //移动到起点
        wavePath.moveTo(startPoint.x.toFloat(), startPoint.y.toFloat())
        var j = 1
        //循环绘制曲线
        for (i in 1..8) {
            val controlX = (startPoint.x + circleLen * j).toFloat()
            //波顶和波底
            val controlY =
                if (i % 2 == 0) (startPoint.y + waveHeight).toFloat() else (startPoint.y - waveHeight).toFloat()
            //二阶贝塞尔
            wavePath.quadTo(
                controlX,
                controlY,
                (startPoint.x + circleLen * 2 * i).toFloat(),
                startPoint.y.toFloat()
            )
            j += 2
        }
        //绘制封闭的区域
        wavePath.lineTo(width.toFloat(), height.toFloat())
        wavePath.lineTo(startPoint.x.toFloat(), height.toFloat())
        wavePath.lineTo(startPoint.x.toFloat(), startPoint.y.toFloat())
        wavePath.close()
        canvas.drawPath(wavePath, wavePaint)
        wavePath.reset()
        //走完一周回到原点
        startPoint.x =
            if (startPoint.x + translateX >= 0) -circleLen * 4 else startPoint.x + translateX
    }
}

到此这篇关于Android自定义View绘制贝塞尔曲线实现流程的文章就介绍到这了,更多相关Android贝塞尔曲线内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android自定义View绘制贝塞尔曲线实现流程

本文链接: https://www.lsjlt.com/news/170524.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android自定义View绘制贝塞尔曲线实现流程
    目录前言二阶贝塞尔曲线三阶贝塞尔曲线前言 对于Android开发,实现贝塞尔曲线还是比较方便的,有对应的API供你调用。由于一阶贝塞尔曲线就是一条直线,实际没啥多大用处,因此,下面主...
    99+
    2022-11-13
    Android 贝塞尔曲线 Android 贝塞尔曲线实现方法
  • Android怎么自定义View绘制贝塞尔曲线
    本文小编为大家详细介绍“Android怎么自定义View绘制贝塞尔曲线”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android怎么自定义View绘制贝塞尔曲线”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。在...
    99+
    2023-07-02
  • Android自定义View绘制贝塞尔曲线的方法
    本文实例为大家分享了Android自定义View绘制贝塞尔曲线的具体代码,供大家参考,具体内容如下 在平面内任选 3 个不共线的点,依次用线段连接。 在第一条线段上任选一个点 D。计...
    99+
    2024-04-02
  • Android自定义view贝塞尔曲线
    本文实例为大家分享了Android自定义view贝塞尔曲线,供大家参考,具体内容如下 贝塞尔曲线 以一个简单的贝塞尔曲线为例,二阶曲线原理 贝塞尔曲线很多功能都会用到,比如小火箭发...
    99+
    2024-04-02
  • Android怎么自定义view贝塞尔曲线
    这篇文章主要介绍了Android怎么自定义view贝塞尔曲线的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android怎么自定义view贝塞尔曲线文章都会有所收获,下面我们一起来看看吧。贝塞尔曲线以一个简单的...
    99+
    2023-07-02
  • Android自定义View绘制贝塞尔曲线中小红点的方法
    目录前言需求效果图代码主要问题简单画法使用贝塞尔曲线前言 上一篇文章用扇形图练习了一下安卓的多点触控,实现了单指旋转、二指放大、三指移动,四指以上同时按下进行复位的功能。今天这篇文章...
    99+
    2023-02-09
    Android绘制贝塞尔曲线 Android贝塞尔曲线小红点
  • Android用Canvas绘制贝塞尔曲线
    用Canvas画贝塞尔曲线,要画贝塞尔曲线首先了解贝塞尔曲线: 由于用计算机画图大部分时间是操作鼠标来掌握线条的路径,与手绘的感觉和效果有很大的差别。即使是一位精明的画师能轻松绘出各...
    99+
    2024-04-02
  • Android怎么用Canvas绘制贝塞尔曲线
    这篇文章主要介绍了Android怎么用Canvas绘制贝塞尔曲线的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android怎么用Canvas绘制贝塞尔曲线文章都会有所收获,下面我们一起来看看吧。用Canvas...
    99+
    2023-07-02
  • Android通过交互实现贝塞尔曲线的绘制
    目录前言获取触控位置交互绘制实现绘制代码运行效果总结前言 之前几篇我们介绍了贝塞尔曲线的原理、绘制曲线和动效实现,这些都是代码预设好的,如果我们要根据需要自行绘制曲线,就需要使用交互...
    99+
    2024-04-02
  • Android 贝塞尔曲线绘制一个波浪球
    目录前言一、绘制 backgroundColor 文本二、构建 circlePath三、绘制波浪线四、取交集五、绘制 foregroundColor 文本六、添加动画七、使用前言 当...
    99+
    2024-04-02
  • Android怎么利用贝塞尔曲线绘制动画
    本篇内容主要讲解“Android怎么利用贝塞尔曲线绘制动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android怎么利用贝塞尔曲线绘制动画”吧!彩虹系列通过动画控制绘制的结束点,就可以让贝...
    99+
    2023-06-30
  • 怎么用Android贝塞尔曲线绘制一个波浪球
    本篇内容介绍了“怎么用Android贝塞尔曲线绘制一个波浪球”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!效果如下所示:先来总结下 Wave...
    99+
    2023-06-30
  • OpenGL 实践中如何进行贝塞尔曲线绘制
    这篇文章给大家介绍OpenGL 实践中如何进行贝塞尔曲线绘制,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。说到贝塞尔曲线,大家肯定都不陌生,网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图。以下两个是比较经典的动图...
    99+
    2023-06-04
  • android实现贝塞尔曲线之波浪效果
    本文实例为大家分享了android实现贝塞尔曲线之波浪效果的具体代码,供大家参考,具体内容如下 1 前言 为了给我以前的博客填坑,这章讲解贝塞尔曲线的几个常用的应用: 1.波浪效果2...
    99+
    2024-04-02
  • Android利用贝塞尔曲线绘制动画的示例代码
    目录彩虹系列弹簧动画复杂立体感动画总结前面我们花了几篇介绍了贝塞尔曲线的原理和绘制贝塞尔曲线,着实让我们见识到了贝塞尔曲线的美。好奇心驱使我想看看贝塞尔曲线动起来会是什么样?本篇就借...
    99+
    2024-04-02
  • 怎么用android实现贝塞尔曲线之波浪效果
    这篇文章主要介绍“怎么用android实现贝塞尔曲线之波浪效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用android实现贝塞尔曲线之波浪效果”文章能帮助大家解决问题。1 前言贝塞尔曲线的...
    99+
    2023-07-02
  • 怎么在Android应用中实现一个贝塞尔曲线
    这篇文章给大家介绍怎么在Android应用中实现一个贝塞尔曲线,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。贝塞尔曲线有一阶、二阶、三阶、N阶 一阶就是一条直线,有起点终点,没有控制点,对应方法就是canvas.dra...
    99+
    2023-05-31
    android 贝塞尔曲线 roi
  • Android贝塞尔曲线实现加入购物车抛物线动画
    本文实例为大家分享了Android贝塞尔曲线实现加入购物车抛物线动画的具体代码,供大家参考,具体内容如下 先上图看效果 步骤: a.确定动画的起终点b.在起终点之间使用二次贝塞...
    99+
    2024-04-02
  • Android自定义一个view ViewRootImpl绘制流程示例
    目录Android如何自定义一个view ViewRootImpl绘制流程1、自定义属性2、在res/layout/activity_main.xml文件里使用自定义view3、构造...
    99+
    2024-04-02
  • Android自定义View实现绘制虚线的方法详解
    前言说实话当第一次看到这个需求的时候,第一反应就是Canvas只有drawLine方法,并没有drawDashLine方法啊!这咋整啊,难道要我自己做个遍历不断的drawLine?不到1秒,我就放弃这个想法了,因为太恶心了。方法肯定是有的,...
    99+
    2023-05-31
    android 自定义view 虚线
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作