安卓自定义控件——等级控件

老规矩 先上渣渣图 我不知道怎么弄高清图

废话不多说 先上代码

class LevelView : View {

    private var widt = 0
    private var heigh = 0

    private var maxLevel = 6 // 等级数量
    private var level = 0.0
    private var levelHeight = 30f // 读条高度
    private var maxScore = 0f
    private var score = 0f
    private var bgColor = 0 // 背景颜色
    private var isGradual = false  // 是否渐变
    private var startColor = 0 // 开始渐变颜色
    private var endColor = 0 // 结束渐变颜色
    private var startText = "V"

    private var lineColor = resources.getColor(R.color.black_33)
    private var mainColor = resources.getColor(R.color.orangeFFC7)

    constructor(context: Context?) : super(context) {}
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs, 0) {
        val ta = context!!.obtainStyledAttributes(attrs, R.styleable.LevelView, 0, 0)

        maxLevel = ta.getInteger(R.styleable.LevelView_maxLevel, 6)
        levelHeight = ta.getDimension(R.styleable.LevelView_levelHeight, 30f)
        maxScore = ta.getFloat(R.styleable.LevelView_maxScore, 0f)
        score = ta.getFloat(R.styleable.LevelView_score, 0f)
        bgColor = ta.getColor(R.styleable.LevelView_bgColor, Color.GRAY)
        isGradual = ta.getBoolean(R.styleable.LevelView_isGradual, false)
        startColor = ta.getColor(R.styleable.LevelView_startColor, Color.WHITE)
        endColor = ta.getColor(R.styleable.LevelView_endColor, Color.WHITE)
        try {
            startText = ta.getString(R.styleable.LevelView_startText)!!
        } catch (e: Exception) {
        }

        // 计算等级
        var oneScore = maxScore / (maxLevel - 1) // 一级的分数是多少

        var l = (score / oneScore)
        level = ceil(l.toDouble())
        if ((l % 1) == 0f) {
            level++
        }
    }
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        widt = w
        heigh = h
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec))
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec))
    }

    private fun measureHeight(measureSpec: Int): Int {
        var result = 0
        var mode = MeasureSpec.getMode(measureSpec);
        var size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.EXACTLY) {
            result = size
        } else {
            result = 75
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size)
            }
        }
        return result
    }

    private fun measureWidth(measureSpec: Int): Int {
        var result = 0;
        var mode = MeasureSpec.getMode(measureSpec)
        var size = MeasureSpec.getSize(measureSpec)

        if (mode == MeasureSpec.EXACTLY) {
            result = size
        } else {
            result = 75;//根据自己的需要更改
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        Log.e("LevelView", level.toString())

        drawBg(canvas!!)
    }

    private fun drawBg(canvas: Canvas) {
        // bg的画笔
        var paint = Paint()
        paint.color = bgColor

        // bg的区域
        var bgRectf = RectF()
        bgRectf.top = 0f
        bgRectf.bottom = levelHeight
        bgRectf.left = 0f
        bgRectf.right = widt.toFloat()

        canvas.drawRoundRect(bgRectf, levelHeight, levelHeight, paint)

        drawScore(canvas)
    }

    private fun drawScore(canvas: Canvas) {

        // Score的画笔
        var paint = Paint()
        paint.color = Color.GREEN

        // Score的区域
        var bgRectf = RectF()
        bgRectf.top = 0f
        bgRectf.bottom = levelHeight
        bgRectf.left = 0f

        if (score == 100f) {
            bgRectf.right = widt.toFloat() * (score / 100f)
        } else {
            bgRectf.right = ((widt.toFloat() * 0.9f) * (score / 100f)) + (widt.toFloat() * 0.05f)
        }


        val colors = IntArray(2)
        val positions = FloatArray(2)

        // 第1个点
        colors[0] = startColor
        positions[0] = 0f

        // 第2个点
        colors[1] = endColor
        positions[1] = 1f

        val shader = LinearGradient(
                0f, 0f,
                widt.toFloat(), 0f,
                colors,
                positions,
                Shader.TileMode.MIRROR)
        paint.shader = shader
        canvas.drawRoundRect(bgRectf, levelHeight, levelHeight, paint)

        drawText(canvas)
    }

    private fun drawText(canvas: Canvas) {
        var oneWith = (widt.toFloat() * 0.9f) / (maxLevel - 1)
        var paddingH = (widt.toFloat() * 0.05f)
        var paddingV = (levelHeight * 0.2f)

        var linePaint = Paint()
        linePaint.color = lineColor
        linePaint.style = Paint.Style.FILL
        linePaint.isAntiAlias = true

        val textPaint = Paint()
        textPaint.textSize = 28f
        textPaint.textAlign = Paint.Align.CENTER
        textPaint.isAntiAlias = true

        var textBgPaint = Paint()

        for (i in 0..maxLevel) {
            // 在等级之前
            if (i < (level - 1)) {
                textPaint.color = mainColor
                textBgPaint.color = Color.TRANSPARENT
            } else if (i == (level.toInt() - 1)) {
                textPaint.color = Color.WHITE
                textBgPaint.color = mainColor
            } else {
                textPaint.color = bgColor
                textBgPaint.color = Color.TRANSPARENT
            }

            var w = (oneWith * i) + paddingH
            canvas.drawRect(w, paddingV + 0, w + 3, levelHeight - paddingV, linePaint)

            val rectF = RectF(w - 35f, levelHeight + 20, w + 35f, levelHeight + 60)

            //计算baseline
            val fontMetrics = textPaint.fontMetrics
            val distance = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
            val baseline = rectF.centerY() + distance

            canvas.drawRoundRect(rectF, 10f, 10f, textBgPaint)
            canvas.drawText(startText + (i + 1), rectF.centerX(), baseline, textPaint)
        }
    }
}

再说思路
第一步 首先绘制一个背景 长条背景
第二步 绘制分数的长条 (渐变色 可要可不要)
第三部 绘制文字
第四步 最最最重要的一点 拿去直接用

有兴趣的朋友可要加点动画啥的

你可能感兴趣的:(安卓自定义控件——等级控件)