高仿小米加载动画效果

前言

首先看一下小米中的加载动画是怎么样的,恩恩~~~~虽然只是张图片,因为录制不上全部,很多都是刚一加载就成功了,一点机会都不提供给我,所以就截了一张图,他这个加载动画特点就是左面圆圈会一直转。

高仿小米加载动画效果

仿照的效果如下:

高仿小米加载动画效果

实现过程

这个没有难度,只是学会一个公式就可以,也就是已知圆心,半径,角度,求圆上的点坐标,算出来的结果在这个点绘制一个实心圆即可,下面是自定义Dialog,让其在底部现实,其中的View也是自定义的一个。


class MiuiLoadingDialog(context: Context) : Dialog(context) {
    private var miuiLoadingView : MiuiLoadingView= MiuiLoadingView(context);
    init {
        setContentView(miuiLoadingView)
        setCancelable(false)
    }

    override fun show() {
        super.show()
        val window: Window? = getWindow();
        val wlp = window!!.attributes

        wlp.gravity = Gravity.BOTTOM
        window.setBackgroundDrawable( ColorDrawable(Color.TRANSPARENT));
        wlp.width=WindowManager.LayoutParams.MATCH_PARENT;
        window.attributes = wlp
    }
}

下面是主要的逻辑,在里面,首先通过clipPath方法裁剪出一个上边是圆角的形状,然后绘制一个外圆,这是固定的。

中间的圆需要一个公式,如下。

x1   =   x0   +   r   *   cos(a   *   PI   /180   ) 
y1   =   y0   +   r   *   sin(a   *   PI  /180   ) 

x0、y0就是外边大圆的中心点,r是中间小圆大小,a是角度,只需要一直变化这个角度,得出的x1、y1通过drawCircle绘制出来即可。

高仿小米加载动画效果


class MiuiLoadingView @JvmOverloads constructor(
    context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : View(context,attrs,defStyleAttr) {

    //Dialog上面圆角大小
    val CIRCULAR: Float = 60f;

    //中心移动圆位置
    var rx: Float = 0f;
    var ry: Float = 0f;

    //左边距离
    var MARGIN_LEFT: Int = 100;

    //中心圆大小
    var centerRadiusSize: Float = 7f;

    var textPaint: Paint = Paint().apply {
        textSize = 50f
        color = Color.BLACK
    }

    var circlePaint: Paint = Paint().apply {
        style = Paint.Style.STROKE
        strokeWidth = 8f
        isAntiAlias = true
        color = Color.BLACK
    }

    var centerCirclePaint: Paint = Paint().apply {
        style = Paint.Style.FILL
        isAntiAlias = true
        color = Color.BLACK
    }

    var degrees = 360;

    val TEXT = "正在加载中,请稍等";
    var textHeight = 0;

    init {

        var runnable = object : Runnable {
            override fun run() {
                val r = 12;
                rx = MARGIN_LEFT + r * Math.cos(degrees.toDouble() * Math.PI / 180).toFloat()
                ry =
                    ((measuredHeight.toFloat() / 2) + r * Math.sin(degrees.toDouble() * Math.PI / 180)).toFloat();
                invalidate()
                degrees += 5
                if (degrees > 360) degrees = 0
                postDelayed(this,1)
            }
        }
        postDelayed(runnable,0)


        var rect = Rect()
        textPaint.getTextBounds(TEXT,TEXT.length,rect)
        textHeight = rect.height()
    }

    override fun onMeasure(widthMeasureSpec: Int,heightMeasureSpec: Int) {
        setMeasuredDimension(widthMeasureSpec,220);
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        var path = Path()
        path.addRoundRect(
            RectF(0f,0f,measuredWidth.toFloat(),measuredHeight.toFloat()),floatArrayOf(CIRCULAR,CIRCULAR,0f),Path.Direction.CW
        );
        canvas.clipPath(path)
        canvas.drawColor(Color.WHITE)


        canvas.drawCircle(
            MARGIN_LEFT.toFloat(),measuredHeight.toFloat() / 2,35f,circlePaint
        )

        canvas.drawCircle(
            rx,ry,centerRadiusSize,centerCirclePaint
        )


        canvas.drawText(TEXT,(MARGIN_LEFT + 80).toFloat(),((measuredHeight / 2)+(textHeight/2)).toFloat(),textPaint)
    }
}

相关文章

AdvserView.java package com.earen.viewflipper; import an...
ImageView的scaleType的属性有好几种,分别是matrix(默认)...
文章浏览阅读8.8k次,点赞9次,收藏20次。本文操作环境:win1...
文章浏览阅读1.2w次,点赞15次,收藏69次。实现目的:由main...
文章浏览阅读3.8w次。前言:最近在找Android上的全局代理软件...
文章浏览阅读2.5w次,点赞17次,收藏6次。创建项目后,运行项...