自定义控件复习-刻度记

2018-10-09  本文已影响0人  隔壁家de老王
身边小伙伴很多人在复习控件,感觉自己也要复习复习了.刚好在学习kotlin,就用kotlin撸一撸,上图上图 device-2018-10-09-164550.png

1,属性定义

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="temperature_view">
        //设置目前的度数
        <attr name="current_temperature" format="float" />
        //指针高度
        <attr name="scale_height" format="dimension" />
        //指针宽度
        <attr name="scale_width" format="dimension" />
        //刻度高度
        <attr name="temperature_height" format="dimension" />
        //指针大小
        <attr name="scale_size" format="dimension" />
        //空间距离
        <attr name="text_space" format="dimension" />
    </declare-styleable>
</resources>

2,刻度记码

package www.test.com.view

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View


class TemperatureView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
    private var currentTemperature: Float = 10f
    private var scaleHeight = 28f
    private var scaleWidth = 18f
    private var temperatureHeight = 20f
    private var temperatureSize = 30f
    private var textSpace = 5f
    private var mPaint: Paint
    private var mPath: Path
    private var scalePaint: Paint
    private var textPaint: Paint
    private var mWidth: Int = 0
    private var mHeight: Int = 0
    private lateinit var bgRectF: RectF
    private lateinit var shader: LinearGradient
    //颜色集合
    private var mColors: IntArray = intArrayOf(Color.GREEN, Color.BLUE, Color.YELLOW)

    init {
        val typeArray = context.obtainStyledAttributes(attrs, R.styleable.temperature_view)
        currentTemperature = typeArray.getFloat(R.styleable.temperature_view_current_temperature, 10f)
        scaleHeight = typeArray.getDimension(R.styleable.temperature_view_scale_height, 28f)
        scaleWidth = typeArray.getDimension(R.styleable.temperature_view_scale_width, 18f)
        temperatureHeight = typeArray.getDimension(R.styleable.temperature_view_temperature_height, 20f)
        temperatureSize = typeArray.getDimension(R.styleable.temperature_view_scale_size, 30f)
        textSpace = typeArray.getDimension(R.styleable.temperature_view_text_space, 5f)
        typeArray.recycle()
        //背景paint
        mPaint = Paint()
        mPaint.isAntiAlias = true
        //绘制文字
        textPaint = Paint()
        textPaint.textSize = temperatureSize
        textPaint.textAlign = Paint.Align.CENTER
        textPaint.color = Color.RED
        //三角指针
        mPath = Path()
        scalePaint = Paint()
        scalePaint.isAntiAlias = true
        scalePaint.style = Paint.Style.FILL
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)
        mWidth = if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY) {
            widthSize
        } else {
            0
        }
        mHeight = if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {
            (temperatureHeight + scaleHeight + textSpace + temperatureSize).toInt()
        } else {
            heightSize
        }
        setMeasuredDimension(mWidth, mHeight)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //初始化背景
        bgRectF = RectF(0f, mHeight - temperatureHeight, mWidth.toFloat(), mHeight.toFloat())
        //初始化线性渐变色
        shader = LinearGradient(0f, mHeight - temperatureHeight, mWidth.toFloat(), mHeight.toFloat(), mColors, null, Shader.TileMode.MIRROR)
        mPaint.shader = shader
    }

    //最大刻度值
    private var max: Float = 100f
    //选择的位置
    private var selectPosition: Float = 0.0f

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        //绘制进度条
        canvas.drawRoundRect(bgRectF, temperatureHeight / 2, temperatureHeight / 2, mPaint)
        selectPosition = currentTemperature / max
        //绘制三角形
        mPath.moveTo(mWidth * selectPosition - scaleWidth / 2, mHeight - temperatureHeight)
        mPath.lineTo(mWidth * selectPosition + scaleWidth / 2, mHeight - temperatureHeight)
        mPath.lineTo(mWidth * selectPosition, mHeight - temperatureHeight - scaleHeight)
        mPath.close()
        scalePaint.shader = shader
        canvas.drawPath(mPath, scalePaint)
        //绘制文字
        val text = currentTemperature.toString() + "℃"
        canvas.drawText(text, mWidth * selectPosition, mHeight - scaleHeight - textSpace - temperatureHeight, textPaint)
    }

    /***
     * 设置目前刻度
     */
    fun setCurrentTemperature(currentTemp: Float) {
        this.currentTemperature = currentTemp
    }
}
上一篇下一篇

猜你喜欢

热点阅读