转载请注明出处 —— http://blog.csdn.net/jjwwmlp456。QQ交流群:473876194
效果图

使用SweepGradient作为paint的shader,用于绘制
paint的color也会影响shader
利用handler不断发送消息,不断改变canvas.drawArc()中的起始角度kotlin中认为类似”0xffffffff”这样,0x后面跟8位数的是long值,在用于颜色时,必须转为Int
在声明Handler成员属性时,不要声明成handler,因为View中有个方法为public Handler getHander();所以kotlin会认为你重写定义了一个属性
package com.stone.stoneviews.widget
import android.content.Context
import android.graphics.*
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
/**
* desc :
* author : stone
* email : aa86799@163.com
* time : 22/07/2017 11 37
*/
class RadarView: View {
private var mRadius = 0f
private var mPaint = Paint()
private var mShader: SweepGradient? = null
private var mRx = 0f
private var mRy = 0f
private val mRingCount = 4
private var mRect: RectF = RectF()
private var mSweepStartAngle = 0f
private var mSweepAngle = 120f
private var mSweepAngleSpeed = 10f
private var mIsStartSweep = false
private val STATE_START = 1
private val STATE_STOP = 2
private val mHandler = object : Handler() {
override fun handleMessage(msg: Message) {
val what = msg.what
when (what) {
STATE_START -> {
mSweepStartAngle += mSweepAngleSpeed
invalidate()
sendMessageDelayed(Message.obtain(this, STATE_START), 50)
}
STATE_STOP -> {
removeCallbacksAndMessages(null)
}
}
}
}
constructor(context: Context) : super(context) {
initParams(context, null, 0)
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
initParams(context, attrs, 0)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initParams(context, attrs, defStyleAttr)
}
fun initParams(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {
val w = resources.displayMetrics.widthPixels
val h = resources.displayMetrics.heightPixels
val min = Math.min(w, h)
mRadius = (min / 2 - 50).toFloat()
mRx = (w / 2).toFloat()
mRy = (h / 2).toFloat()
mPaint.isAntiAlias = true
mRect = RectF(mRx - mRadius, mRy - mRadius, mRx + mRadius, mRy + mRadius)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
mPaint.style = Paint.Style.FILL_AND_STROKE
mPaint.color = Color.BLUE
mPaint.shader = null
canvas.drawCircle(mRx, mRy, mRadius, mPaint)
mPaint.color = Color.parseColor("#abc07f")
mPaint.style = Paint.Style.STROKE
canvas.drawLine(mRx - mRadius, mRy, mRadius + mRx, mRy, mPaint)
canvas.drawLine(mRx, mRy - mRadius, mRx, mRy + mRadius, mPaint)
val eachRingUnit = mRadius / mRingCount
var curRingRadius: Float = 0f
(1 until mRingCount).forEach {
curRingRadius += eachRingUnit
canvas.drawCircle(mRx, mRy, curRingRadius, mPaint)
}
// mShader = SweepGradient(mRx, mRy, 0xddff00f0.toInt(), 0xffabc777.toInt())
mShader = SweepGradient(mRx, mRy, intArrayOf(0xee191970.toInt(), 0xddff000f.toInt(), 0xddff00f0.toInt(), 0xaaff0000.toInt()),
floatArrayOf(0.0f, 0.1f, 0.6f, 0.98f))
mPaint.shader = mShader
mPaint.style = Paint.Style.FILL_AND_STROKE
mPaint.color = Color.parseColor("#ccffffff")
canvas.drawArc(mRect, mSweepStartAngle, mSweepAngle, true, mPaint)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
mIsStartSweep = !mIsStartSweep
if (mIsStartSweep) {
Message.obtain(mHandler, STATE_START).sendToTarget()
} else {
Message.obtain(mHandler, STATE_STOP).sendToTarget()
}
return true
}
}
return super.onTouchEvent(event)
}
}