自定义View圆环上的点随秒钟转动

该博客介绍了如何在Android中自定义一个圆环,并让圆环上的亮点随着秒钟的位置动态移动。通过创建一个CircularRingView类,设置背景圆环并定义亮点的坐标,然后使用线程每秒更新亮点位置,实现了时间流逝的视觉效果。代码中包含了亮点坐标生成和圆环绘制的方法。
摘要由CSDN通过智能技术生成

项目需求:圆环上的亮点,随着秒钟的位置转动

1.自定义圆环

此部分代码仅供参考,我这边自定义了一个简单的白色圆环

public class CircularRingView extends View {
    private int center;
    private int mRadius;
    /**
     * 背景圆环画笔
     */
    private Paint bgPaint;
    /**
     * 圆环的宽度
     */
    private float roundWidth;
    private float startAngle = -90;
    private final static int AngleOfCircle = 360;

    public CircularRingView(Context context) {
        super(context);
    }

    public CircularRingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public CircularRingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CircularRingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    private void initPaint() {

        bgPaint = new Paint();
        roundWidth = 4;
        bgPaint.setStyle(Paint.Style.STROKE);
        bgPaint.setAntiAlias(true);
        bgPaint.setColor(getContext().getColor(R.color.white));
        bgPaint.setStrokeWidth(roundWidth);
        bgPaint.setStrokeWidth(2);


    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //获取圆心的x坐标
        center = Math.min(getWidth(), getHeight()) / 2;
        // 圆环的半径
        mRadius = (int) (center - roundWidth / 2);
        //定义外轮廓矩形
        RectF oval = new RectF(center - mRadius, center - mRadius, center + mRadius, center + mRadius);
        //画背景圆环
        canvas.drawArc(oval, startAngle, AngleOfCircle, false, bgPaint);
    }
}

2.移动外环上的亮点

本项目中点是一张图片

// X和Y 的坐标点 随机复制的,下面会生成
private val secondX703Position: FloatArray by lazy {
        floatArrayOf(175.0F, 190.67928F, 206.18677F, 221.35254F, 236.0105F, 250.0F, 263.1678F, 275.3696F, 286.4717F, 296.35254F, 304.9038F, 312.0318F, 317.65848F, 321.72214F, 324.17828F, 325.0F, 324.17828F, 321.72214F, 317.65848F, 312.0318F, 304.9038F, 296.35254F, 286.4717F, 275.3696F, 263.1678F, 250.0F, 236.0105F, 221.35254F, 206.18677F, 190.67928F, 175.0F, 159.32072F, 143.81325F, 128.64745F, 113.9895F, 100.0F, 86.832214F, 74.6304F, 63.52829F, 53.647453F, 45.09619F, 37.968185F, 32.341522F, 28.277863F, 25.821716F, 25.0F, 25.821716F, 28.277863F, 32.341522F, 37.968185F, 45.09619F, 53.647453F, 63.52829F, 74.6304F, 86.832214F, 100.0F, 113.9895F, 128.64745F, 143.81325F, 159.32072F)
    }

    private val secondY703Position: FloatArray by lazy {
        floatArrayOf(25.0F, 25.821716F, 28.277863F, 32.341522F, 37.968185F, 45.09619F, 53.647453F, 63.52829F, 74.6304F, 86.832214F, 100.0F, 113.9895F, 128.64745F, 143.81325F, 159.32072F, 175.0F, 190.67928F, 206.18677F, 221.35254F, 236.0105F, 250.0F, 263.1678F, 275.3696F, 286.4717F, 296.35254F, 304.9038F, 312.0318F, 317.65848F, 321.72214F, 324.17828F, 325.0F, 324.17828F, 321.72214F, 317.65848F, 312.0318F, 304.9038F, 296.35254F, 286.4717F, 275.3696F, 263.1678F, 250.0F, 236.0105F, 221.35254F, 206.18677F, 190.67928F, 175.0F, 159.32072F, 143.81325F, 128.64745F, 113.9895F, 100.0F, 86.832214F, 74.6304F, 63.52829F, 53.647453F, 45.09619F, 37.968185F, 32.341522F, 28.277863F, 25.821716F)
    }
    private lateinit var secondX703PositionUse: FloatArray
    private lateinit var secondY703PositionUse: FloatArray
    // 圆心坐标点的确定   屏幕的左上角为原点,横的是X  竖的是Y
    private fun initPointArray() {
        val x = 640f //圆心X的坐标
        val y = 360f  //圆心Y的坐标
        val r = 265f   //圆的半径
        val pointWidth = 80f
        for ((index, angle) in (-90 until 270 step 6).withIndex()) {
            secondX703Position[index] = (x + r * cos((angle) / 180.0 * PI) - pointWidth).toFloat()
            secondY703Position[index] = (y + r * sin((angle) / 180.0 * PI) - pointWidth).toFloat()
        }
    }

//秒
private val secondSdf: SimpleDateFormat by lazy {
        SimpleDateFormat(getString(R.string.second_format), Locale.getDefault())
    }
    secondX703PositionUse = secondX703Position
    secondY703PositionUse = secondY703Position
    // 线程每秒去更新坐标点的位置
    private val updateTime = object : Runnable {
        override fun run() {
            val second = secondSdf.format(date).toInt()
            // ivSecondHand是XML中的图片
            ivSecondHand.x = secondXPositionUse[second].toFloat()
            ivSecondHand.y = secondYPositionUse[second].toFloat()
            handler.postDelayed(this, 1000)
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值