效果图:
首先我们要做的是分解当前的view设计,可以分为四个部分:中心绿色的小圆、外面浅绿色的大圆、大圆的阴影和扫描动画。
我们刚开始实现的时候分步走,不要想着一次性就实现整个view。
第一步:画中心绿色的小圆
颜色 :绿色
空心or实心:实心
伪代码实现:
//定义画笔 private val circlePaint = Paint() //中心圆圈画笔 //定义半径 private var circleRadius = 8f //中心圆圈半径 //画笔颜色 circlePaint.color = Color.GREEN //画笔是实心 circlePaint.style = Paint.Style.FILL //在画布上将圆画出来 canvas.drawCircle(width / 2f, height / 2f, circleRadius, circlePaint)
如下图:
第二步:画外面浅绿色的大圆
颜色:浅绿色
空心or实心:实心
伪代码实现:
//定义画笔 private val scanPaint = Paint() //雷达画笔 //定义半径 private var scanCircleRadius = 30f //雷达扫描的半径 //画笔颜色 scanPaint.color = resources.getColor(R.color.radar, null) //空心or实心 scanPaint.style = Paint.Style.FILL //在画布上将圆画出来 canvas.drawCircle(width / 2f, height / 2f, scanCircleRadius, scanPaint)
如下图:
第三步:画大圆的阴影
阴影形状:环形
颜色:从浅绿色到白色
伪代码实现:
//定义阴影 private var scanShader = Shader() //阴影 //形状为SweepGradient类型,以及颜色设置 scanShader = SweepGradient(width / 2f, height / 2f, intArrayOf(resources.getColor(R.color.radar, null), Color.WHITE), floatArrayOf(0f, 1f)) //将阴影赋予画笔 scanPaint.shader = scanShader
如下图:
第四步:实现动画效果
动画:旋转
实现方法:更改阴影角度(或者更改控件角度)
伪代码实现:
private var mRoration = 360f //旋转角度 private var scanMatrix = Matrix() //阴影矩阵 //将矩阵赋予给阴影 scanShader.setLocalMatrix(scanMatrix) //每绘制一次就改变阴影角度 override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) if (mRoration <= 0) { mRoration = 360f } mRoration -= 2 scanMatrix.setRotate(mRoration, width / 2f, height / 2f) scanShader.setLocalMatrix(scanMatrix) }
再稍微调整下某些变量,这样基本就完成整个自定义view的开发了,是不是感觉也挺简单的。
下面是完整代码:
package com.fht.kotlin.widget import android.annotation.SuppressLint import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.View import com.fht.kotlin.R class RadarView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyelAttr: Int = 0) : View(context, attrs, defStyelAttr) { private val scanPaint = Paint() //雷达画笔 private val circlePaint = Paint() //中心圆圈画笔 private var scanCircleRadius = 0f //雷达扫描的半径 private var circleRadius = 0f //中心圆圈半径 private var mRoration = 360f //旋转角度 private var scanShader = Shader() //阴影 private var scanMatrix = Matrix() //阴影矩阵 private var stopScan = false init { scanPaint.color = resources.getColor(R.color.radar, null) scanPaint.isAntiAlias = true scanPaint.style = Paint.Style.FILL circlePaint.color = Color.GREEN circlePaint.isAntiAlias = true circlePaint.style = Paint.Style.FILL } fun startScan() { stopScan = false invalidate() } fun stopScan() { stopScan = true } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) scanCircleRadius = w / 2f circleRadius = scanCircleRadius * 0.035f //计算半径 } override fun onAttachedToWindow() { super.onAttachedToWindow() startScan() } override fun onDetachedFromWindow() { super.onDetachedFromWindow() stopScan() } @SuppressLint("DrawAllocation") override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { super.onLayout(changed, left, top, right, bottom) scanShader = SweepGradient(width / 2f, height / 2f, intArrayOf(resources.getColor(R.color.radar, null), Color.WHITE), floatArrayOf(0f, 1f)) scanPaint.shader = scanShader scanShader.setLocalMatrix(scanMatrix) } override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) if (canvas != null) { canvas.drawCircle(width / 2f, height / 2f, scanCircleRadius, scanPaint) canvas.drawCircle(width / 2f, height / 2f, circleRadius, circlePaint) setRotation() } } private fun setRotation() { if (mRoration <= 0) { mRoration = 360f } mRoration -= 2 scanMatrix.setRotate(mRoration, width / 2f, height / 2f) scanShader.setLocalMatrix(scanMatrix) if (!stopScan) { invalidate() } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)