美文网首页android
倒计时边框

倒计时边框

作者: WLHere | 来源:发表于2020-09-09 21:18 被阅读0次

实现效果

SVID_20200909_211048_1.gif

xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:elevation="0dp"
    android:gravity="right|center_vertical"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.example.test.view.TimerBg
        android:layout_width="100dp"
        android:layout_height="150dp"
        android:background="#0000ff" />

</LinearLayout>

code

/**
 * 边框倒计时控件
 */
class TimerBg(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs) {
    var totalTime = 10000// 总时间
    var leftTime = 10000// 剩余时间
    private val mAnglePath = Path()// 切圆角path
    private val mProgressPath = Path()// 进度path
    private val mProgressPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private var mAngleRadius = 0f// 圆角半径
    private var mAngleDiameter = 0f// 圆角直径
    private var mAngleLength = 0f// 圆角边长
    private val mLTAngleRect = RectF()
    private val mLBAngleRect = RectF()
    private val mLineWidth: Float

    private var lastTime = 0L

    init {
        setWillNotDraw(false)
        mAngleRadius = DensityUtil.dip2px(context, 10f).toFloat()
        mAngleDiameter = 2 * mAngleRadius
        mAngleLength = (Math.PI * mAngleRadius / 2).toFloat()
        mLineWidth = DensityUtil.dip2px(context, 6f).toFloat()
        mProgressPaint.let {
            it.style = Paint.Style.STROKE
            it.color = 0xffff0000.toInt()
            it.strokeWidth = mLineWidth
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mLTAngleRect.set(0f, 0f, mAngleDiameter, mAngleDiameter)
        mLBAngleRect.set(0f, h.toFloat() - mAngleDiameter, mAngleDiameter, h.toFloat())
        // 设置圆角path
        mAnglePath.reset()
        mAnglePath.moveTo(w.toFloat(), 0f)
        mAnglePath.lineTo(w.toFloat(), h.toFloat())
        mAnglePath.lineTo(mAngleRadius, h.toFloat())
        mAnglePath.arcTo(mLBAngleRect, 90f, 90f)
        mAnglePath.lineTo(0f, mAngleRadius)
        mAnglePath.arcTo(mLTAngleRect, 180f, 90f)
        mAnglePath.close()
    }

    override fun draw(canvas: Canvas?) {
        // 绘制圆角
        canvas?.save()
        canvas?.clipPath(mAnglePath)
        super.draw(canvas)
        canvas?.restore()
    }

    // 绘制进度条
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        if (canvas == null) {
            return
        }
        if (totalTime > 0 && leftTime <= 0) {
            return
        }
        // 设置边框范围
        val left = 0f
        val top = 0f
        val right = canvas.width.toFloat()
        val bottom = canvas.height.toFloat()
        val width = right - left
        val height = bottom - top

        // 总边长
        val totalSideLength = (width - mAngleRadius) * 2 + (height - mAngleDiameter) + mAngleLength * 2

        // 获取进度
        val progressPer = if (totalTime > 0) {
            leftTime.toFloat() / totalTime
        } else {
            1f
        }
        // 获取进度长度
        var leftProgressLength = totalSideLength * progressPer
        // 重置path
        mProgressPath.reset()
        mProgressPath.moveTo(right, top)

        // 添加path
        // 从左上角开始绘制
        if (leftProgressLength >= width - mAngleRadius) {
            mProgressPath.lineTo(left + mAngleRadius, top)// 上边直线
            leftProgressLength -= width - mAngleRadius
            if (leftProgressLength >= mAngleLength) {
                mProgressPath.arcTo(mLTAngleRect, 270f, -90f)// 左上角
                leftProgressLength -= mAngleLength
                if (leftProgressLength >= height - mAngleDiameter) {
                    mProgressPath.lineTo(left, bottom - mAngleRadius)// 左边直线
                    leftProgressLength -= height - mAngleDiameter
                    if (leftProgressLength >= mAngleLength) {
                        mProgressPath.arcTo(mLBAngleRect, 180f, -90f)// 左下角
                        leftProgressLength -= mAngleLength
                        mProgressPath.lineTo(left + mAngleRadius + leftProgressLength, bottom)// 下边直线
                    } else {
                        mProgressPath.arcTo(mLBAngleRect, 180f, -90f * leftProgressLength / mAngleLength)// 左下角
                    }
                } else {
                    mProgressPath.lineTo(left, bottom - mAngleRadius - ((height - mAngleDiameter) - leftProgressLength))// 左边直线
                }
            } else {
                mProgressPath.arcTo(mLTAngleRect, 270f, -90f * leftProgressLength / mAngleLength)// 左上角
            }
        } else {
            mProgressPath.lineTo(left + width - leftProgressLength, top)// 上边直线
        }
        canvas.drawPath(mProgressPath, mProgressPaint)

        if (lastTime == 0L) {
            lastTime = SystemClock.elapsedRealtime()
            invalidate()
        } else {
            val curTime = SystemClock.elapsedRealtime()
            leftTime -= (curTime - lastTime).toInt()
            lastTime = curTime

            if (leftTime < 0) {
                leftTime = 0
            }
            if (leftTime >= 0) {
                invalidate()
            }
        }
    }
}

相关文章

  • 倒计时边框

    实现效果 xml code

  • PS零基础入门课程作业-动画制作

    倒计时制作: 新建画板---填色--加文字“倒计时”---加边框。 复制图层,分别做好01、02、03、GO这四个...

  • Axure-2步实现倒计时

    1.拖入文本框>隐藏边框&填充>输入最初数字 2.给文本框命名为“倒计时”>选中“倒计时”加事件 2.1载入时:等...

  • CSS盒子模型

    边框:环绕在标签周围的边条 设置边框一:-连写格式:同时设置4条边框{border:边框宽度 边框样式 边框颜色;...

  • 25.边框圆角渐变

    边框 什么是边框圆角?将直角的边框变为圆角的边框 边框圆角的格式?border-radius: 左上 右上 右下 ...

  • 07-CSS盒模型

    边框属性 边框属性的格式连写(同时设置四条边的边框)border: 边框的宽度 边框的样式 边框的颜色;快捷键:b...

  • 边框border

    边框的组成:边框的粗细,边框的样式,边框的颜色 border: 1px solid red 边框的粗细:单位为px...

  • SwiftUI 设置边框、透明度、阴影

    前言 1、设置边框 1.1 设置边框颜色 默认为1的边框 解释 1.2 设置边框颜色、宽度 设置边框颜色、宽度 2...

  • 2.css盒模型

    1 盒子模型的概念 2.边框属性 3.边框属性—设置边框样式(border-style) 4.边框属性—设置边框样...

  • CSS边框圆角--跟着李南江学编程

    1.什么是边框圆角? 就是把矩形边框变成圆角边框,就叫做边框圆角。 2.设置边框圆角的格式 2.1 border-...

网友评论

    本文标题:倒计时边框

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