前言
在进入小程序前,会有一个加载动画,如下所示,中心是小程序图标,外圈是一个绿色的圆形进度,这个圈会根据加载的进度而绘制。
仿照效果如下
下面是实现步骤
绘制圆形图片
第一步是绘制一个圆形图片,这里使用kotlin的扩展函数创建一个getCircledBitmap,用来获取Bitmap对应的圆角图片。
fun Bitmap.getCircledBitmap(): Bitmap {
val output = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint()
val rect = Rect(0, 0, this.width, this.height)
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
canvas.drawCircle(this.width / 2f, this.height / 2f, this.width / 2f, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(this, rect, rect, paint)
return output
}
复制代码
初始化
在init函数中进行初始化,事先创建好一个Bitmap,利用postDelayed函数重复执行Runnable,内部对startAngle和progress进行自增。startAngle代表起始角度,因为这个圈会一直转着,progress表示进度,在利用drawArc绘制绘制圆弧时,progress表示角度,当360度时,就是绘制了一个完整的圆圈。
class MiniLoading @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
var progress: Float = 0f
var startAngle: Float = 0f;
val IMAGE_SIZE: Int = 162;
val CIRCLE_SIZE: Float = ((IMAGE_SIZE / 2) + 20).toFloat()
var bitmapLogo: Bitmap;
init {
var bitmap = BitmapFactory.decodeResource(resources, R.drawable.back)
var matrix = Matrix()
matrix.setScale(IMAGE_SIZE / bitmap.width.toFloat(), IMAGE_SIZE / bitmap.width.toFloat())
bitmapLogo = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, false)
.getCircledBitmap()
var runnable = object : Runnable {
override fun run() {
startAngle += 5
progress=if (progress>360) 0f else progress+2
invalidate()
postDelayed(this, 1)
}
}
postDelayed(runnable, 0)
}
复制代码
绘制内容
最后一步在onDraw中绘制三个部分,第一部分是中间图片,第二部分是一个浅色的"轨道",第三部分是进度。
override fun onDraw(canvas: Canvas) {
canvas.drawBitmap(
bitmapLogo,
(width / 2) - (IMAGE_SIZE / 2).toFloat(),
-((bitmapLogo.height - height) / 2).toFloat(),
Paint()
)
canvas.drawCircle(
(width / 2).toFloat(),
(height / 2).toFloat(),
CIRCLE_SIZE,
Paint().apply {
style = Paint.Style.STROKE
color = Color.parseColor("#E1DEE1")
})
val oval = RectF()
oval.left = width / 2f - (CIRCLE_SIZE)
oval.top = height / 2f - (CIRCLE_SIZE)
oval.right = oval.left + CIRCLE_SIZE * 2
oval.bottom = oval.top + CIRCLE_SIZE * 2
canvas.drawArc(oval, startAngle, progress, false, Paint().apply {
style = Paint.Style.STROKE
strokeWidth = 5f
color = Color.parseColor("#FF269F34")
})
复制代码