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
}
}