Android开发(18)——自定义加载动画(2):脉搏跳动动画

2021-04-07  本文已影响0人  让时间走12138

本节内容

1.脉搏跳动加载动画分析

2.重确定半径

3.两种方式绘制三个圆

4.实现跳动动画

一、脉搏跳动加载动画分析
1.效果如下图所示。就是三个点不断放大缩小的过程。
QQ图片20210406195227.png
QQ图片20210406195224.png
2.首先建模,计算一下半径。为了避免出现上一个demo中出现的,绘制到外面去的情况出现,我们就以最小的那个为标准。
  • 6R+0.5R+0.5R = minSize ----> R = minSize/7
  • Cx =width/2 -2R-0.2R(第一个圆的横坐标)我们以中间圆的坐标为中心点
  • Cy = height/2
image.png
二、确定半径
1.先创建一个类,然后实现三个构造方法
class PauseLoadingView : View {
    constructor(context: Context):super(context){}
    constructor(context: Context, attrs: AttributeSet?):super(context,attrs){}
    constructor(context: Context, attrs: AttributeSet?, style:Int):super(context,attrs,style){}
}
2.定义几个变量,包括半径,第一个圆的坐标,并且提供一支画笔
//圆球的半径
    private var radius = 0f
    //第一个球的中心点坐标
    private var cx= 0f
    private var cy = 0f

    private val mPaint = Paint().apply {
        color = context.resources.getColor(R.color.colorAccent,null)
        style = Paint.Style.FILL
    }
3.在onSizeChanged方法里面计算一下半径
 override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        radius = Math.min(measuredHeight,measuredWidth)/7f
        cx= (measuredWidth/2f - 2.5*radius).toFloat()
        cy = measuredHeight/2f
}
4.在onDraw方法里面先绘制一个圆
 override fun onDraw(canvas: Canvas?) {
          canvas?.drawCircle(cx,cy,radius,mPaint)
}
5.这样一定可以画出来完整的圆,但是并不能贴满画布。如果想要贴满的话,我们可以再设置一下。
 override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        
       if(measuredWidth>= measuredHeight){
           radius = measuredHeight/2f
           //确定宽度是否能过容纳下
           if(7*radius>measuredWidth){
               //重新计算radius
               radius = measuredWidth/7f
           }
       }else{
          radius = measuredWidth/7f
           //确定高度是否能够容纳下
           if(2*radius>measuredHeight){
           radius = measuredHeight/2f
           }
       }
        cx= (measuredWidth/2f - 2.5*radius).toFloat()
        cy = measuredHeight/2f
    }
三、两种方式绘制三个圆
1.直接绘制,把三个圆的圆心直接给出来。
        canvas?.drawCircle(cx,cy,radius,mPaint)
        canvas?.drawCircle(cx+2.5f*radius,cy,radius,mPaint)
        canvas?.drawCircle(cx+5f*radius,cy,radius,mPaint)
2.移动画布来画圆,每次都以(0,0)为圆心,R为半径画三个圆,最后再把画布放回去。
 for(i in 0..2){
            canvas?.save()//把之前的状态保存下来
            canvas?.translate(cx+i*2.5f*radius,cy)//将画布移动到这个位置
            canvas?.drawCircle(0f,0f,radius,mPaint)//然后绘制一个圆
            canvas?.restore()
        }
四、实现跳动动画
1.添加一下提供给外部的方法来启动和停止动画
 //启动动画
    fun show(){
        createAnimator()
       start()
    }
    //隐藏动画
    fun hide(){
      stop()
    }
  • 2.为了让它们看起来有从小变大,从大变小的效果,我们要设置一下动画的延时时间,每个圆的延时时间都不同。
  • canvas有一个功能,可以获取当前view的scale,所以我们可以将缩放比例作为动画因子。
 //动画因子  缩放的比例
    private var mScale = 1.0f
    //动画对象
    private var mAnimators = mutableListOf<ValueAnimator>()
    //保存延时的时间
    private val delays = arrayOf(120L,240L,360L)
  //保存每个圆缩放的比例
    private val scales = arrayOf(1f,1f,1f)
3.在onDraw方法的for循环里,获取每个圆点对应的缩放比例
canvas?.scale(scales[i],scales[i])  //获取每个圆点对应的缩放比例
4.写一个createAnimator()方法,来实现动画效果。缩放比例从1f---->0.4f
 private fun createAnimator(){
        for(i in 0..2){
        ValueAnimator.ofFloat(1f,0.4f).apply {
            duration = 600
            //设置每个圆点对应的延迟时间
            startDelay = delays[i]
            repeatCount = ValueAnimator.INFINITE
            addUpdateListener {
                scales[i] =   it.animatedValue as Float  //设置每个圆点对应的缩放因子的值
                invalidate()
            }
          mAnimators.add(this)
        }
    }
    }
5.实现一下start()和stop()方法
private fun start(){
        for (item in mAnimators){
            item.start()
        }
    }
    private  fun stop(){
        for (item in mAnimators){
            item.end()
        }
    }
上一篇下一篇

猜你喜欢

热点阅读