美文网首页
信用仪表

信用仪表

作者: sometimes_ | 来源:发表于2020-09-02 13:38 被阅读0次
android.gif
class CreditMeter @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {


    private val _color_progress_bg = Color.parseColor("#f0f0f0") //进度背景
    private val _color_grade_excellent = Color.parseColor("#0084FF")  //主颜色
    private val _color_grade = Color.parseColor("#999999")
    private val _color_fraction = Color.parseColor("#333333")
    private val _color_pointer = _color_grade_excellent //指针颜色
    private val maxFraction = 100f //最大分数
    private val maxAngle = 270f //进度条划过最大角度
    private val progressWidth = 40f
    private val pointerWidth = 6f //指针宽度
    private var scaleSpinAngle = 50f //刻度标记市相对于中间刻度的角度
    private var currentAnimationProgress = 0f //当前动画执行进度
        set(value) {
            field = value
            postInvalidate()
        }
    private var currentFraction: Int = 0 //当前信用等级分数
        set(value) {
            field = value
            postInvalidate()
        }
    private val currentFractionGradeValue: String //当前分数对应等级
        get() {
            return when {
                currentFraction < 60 -> {
                    "信用差"
                }
                currentFraction < 80 -> {
                    "信用中等"
                }
                currentFraction < 90 -> {
                    "信用良好"
                }
                else -> {
                    "信用优秀"
                }
            }
        }

    private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val textPaint = TextPaint(progressPaint)
    private val paintPointer = Paint(progressPaint)
    private val oval = RectF() //绘制范围

    init {
        progressPaint.style = Paint.Style.STROKE
        progressPaint.strokeWidth = progressWidth

        //指针画笔
        paintPointer.style = Paint.Style.STROKE
        paintPointer.color = _color_pointer
        paintPointer.strokeWidth = pointerWidth

        //文字画笔
        textPaint.color = _color_fraction
        textPaint.textAlign = Paint.Align.CENTER
        textPaint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val widthModel = MeasureSpec.getMode(widthMeasureSpec)
        var widthSize = MeasureSpec.getSize(widthMeasureSpec)
        var heightSize = MeasureSpec.getSize(heightMeasureSpec)
        when (widthModel) {
            MeasureSpec.UNSPECIFIED -> { //不限制
                widthSize = 200
            }

            MeasureSpec.AT_MOST -> { //最大只能 Match

            }

            MeasureSpec.EXACTLY -> { //指定

            }
        }

        if (widthSize < heightSize) {
            heightSize = widthSize
        } else {
            widthSize = heightSize
        }
        setMeasuredDimension(widthSize, heightSize)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas ?: return
        //绘制背景圆弧
        drawBackground(canvas)
        //绘制刻度
        drawCalibration(canvas)
        //绘制等级文字
        relDrawCalibrationContent(canvas)
        //绘制进度条
        drawProgress(canvas)
        //绘制当前分数
        drawGradeAndFraction(canvas)
        //绘制中心圆和指针
        drawPointer(canvas)
    }


    /**
     * 绘制背景圆弧
     */
    private fun drawBackground(canvas: Canvas) {
        progressPaint.style = Paint.Style.STROKE
        progressPaint.strokeWidth = progressWidth
        progressPaint.color = _color_progress_bg
        oval.set(
            progressPaint.strokeWidth / 2,
            progressPaint.strokeWidth / 2,
            measuredWidth.toFloat() - progressPaint.strokeWidth / 2,
            measuredHeight.toFloat() - progressPaint.strokeWidth / 2
        )
        canvas.drawArc(oval, 135f, maxAngle, false, progressPaint)
    }

    /**
     * 绘制刻度等级区分
     * 中间刻度线 270度
     * 旋转-50
     * 旋转+1000
     * 旋转-50
     * 绘制文字
     */
    private fun drawCalibration(canvas: Canvas) {
        progressPaint.style = Paint.Style.FILL_AND_STROKE
        progressPaint.color = _color_grade_excellent
        progressPaint.strokeWidth = 4f
        relDrawCalibration(canvas)
        canvas.rotate(-scaleSpinAngle, (width / 2).toFloat(), (height / 2).toFloat())
        relDrawCalibration(canvas)
        canvas.rotate(scaleSpinAngle * 2, (width / 2).toFloat(), (height / 2).toFloat())
        relDrawCalibration(canvas)
        canvas.rotate(-scaleSpinAngle, (width / 2).toFloat(), (height / 2).toFloat())

    }

    /**
     * 绘制刻度
     * 角度区间为50度
     */
    private fun relDrawCalibration(canvas: Canvas) {
        paintPointer.strokeWidth = 6f
        canvas.drawLine(
            (measuredWidth / 2).toFloat(),
            progressWidth + 4f,
            (measuredWidth / 2).toFloat(),
            progressWidth + 30f, paintPointer
        )

    }

    /**
     * 绘制刻度文字提示
     */
    private fun relDrawCalibrationContent(canvas: Canvas) {
        textPaint.textSize = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP, 12f,
            resources.displayMetrics
        )
        textPaint.color = _color_grade
        getPointerFromAngleAndRadius(
            (maxAngle - scaleSpinAngle / 2).toInt(),
            (width / 2 - progressWidth * 2.5).toInt()
        ).apply {
            canvas.drawText("中", this[0], this[1], textPaint)
        }

        getPointerFromAngleAndRadius(
            (maxAngle - scaleSpinAngle * 1.5).toInt(),
            (width / 2 - progressWidth * 2.5).toInt()
        ).apply {
            canvas.drawText("差", this[0], this[1], textPaint)
        }

        getPointerFromAngleAndRadius(
            (maxAngle + scaleSpinAngle / 2).toInt(),
            (width / 2 - progressWidth * 2.5).toInt()
        ).apply {
            canvas.drawText("良", this[0], this[1], textPaint)
        }

        getPointerFromAngleAndRadius(
            (maxAngle + scaleSpinAngle * 1.5).toInt(),
            (width / 2 - progressWidth * 2.5).toInt()
        ).apply {
            canvas.drawText("优", this[0], this[1], textPaint)
        }

    }

    /**
     * 绘制信用等级以及分数
     */
    private fun drawGradeAndFraction(canvas: Canvas) {

        textPaint.textSize = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP, 17f,
            resources.displayMetrics
        )

        textPaint.color = _color_fraction
        val fontMetrics = textPaint.fontMetrics
        val textHeight = fontMetrics.bottom - fontMetrics.top

        //绘制信用分数
        canvas.drawText(
            "$currentFraction",
            (width / 2).toFloat(),
            height - progressWidth,
            textPaint
        )


        textPaint.textSize = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP, 12f,
            resources.displayMetrics
        )
        textPaint.color = _color_grade
        //信用等级
        canvas.drawText(
            currentFractionGradeValue,
            (width / 2).toFloat(),
            height - textHeight - progressWidth,
            textPaint
        )
    }

    /**
     * 需要动画
     * 需要指针
     */
    private fun drawProgress(canvas: Canvas) {
        //绘制当前进度
        /**************以下为绘制进度***************/
        progressPaint.style = Paint.Style.STROKE
        progressPaint.color = _color_grade_excellent
        progressPaint.strokeWidth = progressWidth
        canvas.drawArc(oval, 135f, currentAnimationProgress, false, progressPaint)
    }

    /**
     * 绘制指针
     */
    private val pointerPath = Path()
    private fun drawPointer(canvas: Canvas) {
        //绘制中心指针圆

        canvas.drawCircle(
            (measuredWidth / 2).toFloat(),
            (measuredHeight / 2).toFloat(),
            16f,
            paintPointer
        )

        val angle = currentAnimationProgress + 135f //当前指针的角度
        val currentPointerPoint = getPointerFromAngleAndRadius(angle.toInt(), width / 4)

        val centerCirclePoint = getPointerFromAngleAndRadius(angle.toInt(), 16)

        pointerPath.moveTo(centerCirclePoint[0], centerCirclePoint[1])
        pointerPath.lineTo(currentPointerPoint[0], currentPointerPoint[1])
        pointerPath.close()
        canvas.drawPath(pointerPath, paintPointer)
        pointerPath.reset()
    }

    /**
     * 得到当前指针
     * 在当前角度下 当前半径下的 外切圆点
     */
    private fun getPointerFromAngleAndRadius(angle: Int, radius: Int): FloatArray {
        val x = radius * cos(angle * Math.PI / 180) + width / 2
        val y = radius * sin(angle * Math.PI / 180) + height / 2
        return floatArrayOf(x.toFloat(), y.toFloat())
    }

    /**
     * 进度动画
     * 指针动画
     */
    fun startAnimation(targetProgress: Int) {
        val progress: Float
        val scale = targetProgress / maxFraction
        when {
            scale < 0.6 -> {
                //当前的进度配分为格格
                progress = ((maxAngle / 2 - scaleSpinAngle) / 60) * targetProgress
            }

            scale < 0.8 -> {
                progress =
                    (maxAngle / 2 - scaleSpinAngle) + (scaleSpinAngle / 20) * (targetProgress - 60)
            }

            scale < 0.9 -> {
                progress = maxAngle / 2 + (scaleSpinAngle / 10) * (targetProgress - 80)
            }
            else -> {
                val scaleAngle90 = maxAngle / 2 + scaleSpinAngle //90分刻度的扫过角度
                progress = scaleAngle90 + ((maxAngle - scaleAngle90) / 60) * (targetProgress - 90)
            }
        }

        val fractionAni = ObjectAnimator.ofInt(this, "currentFraction", 0, targetProgress)
        val progressAni = ObjectAnimator.ofFloat(this, "currentAnimationProgress", 0f, progress)
        AnimatorSet().apply {
            playTogether(progressAni, fractionAni)
            duration = 500
            interpolator = AccelerateDecelerateInterpolator()
            start()
        }
    }
}

相关文章

  • 信用仪表

  • Android自定义控件

    自定义 View 之高仿支付宝芝麻信用分仪表盘效果 最近写的一个自定义 View,仿了下支付宝新旧版的芝麻信用分的...

  • iOS芝麻信用仪表盘效果(一)

    整体效果如下 (一)做出白点旋转效果大致说一下基础工作和需求: 基础工作:UI做好的表盘一个(可以自己绘制),带白...

  • 仪表郎 - 草稿

    仪表强,则装置强 仪表优,则装置优 仪表稳,则装置稳 仪表安全,则装置安全! 仪表自有仪表狂! 天南地北 烈日风...

  • 仪表郎

    仪表强,则装置强 仪表优,则装置优 仪表稳,则装置稳 仪表安全,则装置安全! 仪表自有仪表狂! 天南地北 烈日风...

  • iOS仿支付宝芝麻信用仪表盘效果

    自定义View之高仿支付宝芝麻信用分数仪表盘动画效果 主要思路: 1.圆环上绿点的旋转 2.分数值及提示语的变化 ...

  • 仪表

    我娘俩在家,我在写文章,儿子也在写文章,有人敲门,儿子动身去开门,看我起身了,然后折回去,原来是社区做满意度调查的...

  • 仪表故障处理经验

    仪表故障处理经验 世界工业网络关键词:仪表维修理念、常见仪表故障处理总结 1结晶在现有装置中,加氢脱硫塔的有关仪表...

  • JIRA使用总结(四)——仪表盘

    仪表盘是大家在使用JIRA管理项目时都会用到的工具。 入口:仪表盘—管理仪表盘,创建仪表盘同时可设置共享人员,参考...

  • ECharts仪表盘样式

    【ECharts,仪表盘样式1】 Vue仪表盘样式vue代码 总计 Vue仪表盘样式js代码 drawLin...

网友评论

      本文标题:信用仪表

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