美文网首页
Android自定义View--转圈圈

Android自定义View--转圈圈

作者: 看见对方 | 来源:发表于2020-05-20 16:34 被阅读0次

Android自定义View–转圈圈

看GIF图说话,用代码实现这个效果

先以圆心a 画半径100的圆,在画一个半径150的圆c,以圆c上的点为半径画圆b,每隔5度画一个圆b,之后根据画圆b时的角度在圆b上画一个圆d,当大于180度时画圆的角度要用360度减去当前的度数。

首先肯定是测量View的大小了

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

        var w = 0

        var h = 0

        val wMode = MeasureSpec.getMode(widthMeasureSpec)

        if (wMode == MeasureSpec.AT_MOST) {

            w = widthC+paddingLeft+paddingRight

        } else if (wMode == MeasureSpec.EXACTLY) {

            w = MeasureSpec.getSize(widthMeasureSpec)+paddingLeft+paddingRight

        }

        val hMode = MeasureSpec.getMode(heightMeasureSpec)

        if (hMode == MeasureSpec.AT_MOST) {

            h = hightC+paddingTop+paddingBottom

        } else if (hMode == MeasureSpec.EXACTLY) {

            h = MeasureSpec.getSize(heightMeasureSpec)+paddingTop+paddingBottom

        }

        widthC = w

        hightC = h

        setMeasuredDimension(

            MeasureSpec.makeMeasureSpec(w, wMode),

            MeasureSpec.makeMeasureSpec(h, hMode)

        )

    }

计算圆上的坐标

pointX = x + radius * Math.cos(Math.toRadians(angle))//angle是弧度

pointY = y + radius * Math.sin(Math.toRadians(angle))

画出圆b

    val realW = widthC - paddingLeft - paddingRight

    val realH = hightC - paddingTop - paddingBottom

    val centerRadius: Double = min(realW, realH) * 0.1875  //0.1875是计算圆c的半径 一个比例 150/800=0.1875   

    val circleRadius=min(realW, realH) * 0.3125 //0.3125是计算圆b的半径的一个比例  250/800=0.3125

    for (i in 0..360 step 5) {//每5度画一个圆

        val circleX =

            ((centerRadius * cos(

                Math.toRadians(

                    i.toDouble()

                )

            )) + widthC / 2f).toFloat()

        val circleY =

            ((centerRadius * sin(Math.toRadians(i.toDouble()))) + hightC / 2f).toFloat()

        canvas?.drawCircle(circleX, circleY, circleRadius.toFloat(), circlePaint)

    }

通过上面画出一下的圆

在通过一下代码将圆d画到圆b上

        canvas?.drawCircle(

            ((circleRadius * cos(

                Math.toRadians(

                    if (i in 0..180 && i == 360) getOffset(i) else getOffset(

                        360 - i

                    )

                )

            )) + circleX).toFloat(),

            (circleRadius * sin(

                Math.toRadians(

                    if (i in 0..180 && i == 360) getOffset(i) else getOffset(

                        360 - i

                    )

                )

            ) + circleY).toFloat(),

            5f,

            dotPaint

        )

  /**

    *@param i

    * @param s 圆点的初始角度 默认0

    */

    private fun getOffset(i: Int,s:Int=0): Double = (if (i == 360) {

        0 + offset % 360+s

    } else {

        i + offset % 360+s

    }).toDouble()

这样就画好了,如下图

最后去掉蓝色圆,添加计时器每16ms重绘一次,这样就可以动起来了

private var offset = 360

Timer().schedule(object : TimerTask() {

            override fun run() {

                offset++

                invalidate()

            }

        }, 16, 16)

还可以弄成下面的样式:

相关文章

网友评论

      本文标题:Android自定义View--转圈圈

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