高仿微信小程序进入时加载动画

前言

在进入小程序前,会有一个加载动画,如下所示,中心是小程序图标,外圈是一个绿色的圆形进度,这个圈会根据加载的进度而绘制。

image.png

仿照效果如下

录屏_选择区域_20211008115358.gif

下面是实现步骤

绘制圆形图片

第一步是绘制一个圆形图片,这里使用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")
    })
复制代码

猜你喜欢

转载自juejin.im/post/7016539036495904776
今日推荐