运维开发网

Android开发的自定义加载动画详解

运维开发网 https://www.qedev.com 2022-09-04 20:37 出处:网络
这篇文章主要介绍了Android开发的自定义加载动画,效果为一个连续的动画,就是这个大圆不停地吞下小圆,文中示例代码讲解详细,感兴趣的可以了解一下

这篇文章主要介绍了Android开发的自定义加载动画,效果为一个连续的动画,就是这个大圆不停地吞下小圆,文中示例代码讲解详细,感兴趣的可以了解一下


一、demo简介

1.效果如下图所示。我切了三个瞬间,但其实这是一个连续的动画,就是这个大圈不停的吞小。


2.这个动画可以分为两部分。第一,大圆张开嘴闭上嘴的动画相当于画了一个圆弧,指定它的角度就好了。圆圈是从右向左移动的动画。然后不断刷新界面,让动画的持续时间是永恒的,这样才会有持续的动态效果。


二、分析贪吃动画的尺寸比例

1.在制作动画之前,我们要建立一个模型,确定大圆和小圆的比例。这个比例是自己设定的,可以自己修改。下图是画布宽度大于高度的情况。

R =最小高度/6

Cx =(宽度-最小宽度)/2 + 3R

Cy =高度/2


还有画布宽度小于高度的情况,如下图所示:此时

6R+0.5R+2R =最小宽度.R =最小宽度/8.5

Cx = 3R

Cy =高度/2


2.确定了大圆的圆心坐标后,也可以知道小圆的圆心坐标。


三、画圆

1.首先创建一个从view继承的类,并实现其对应的构造方法。

class MouseLoadingView : 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.定义大圆(嘴)的半径(3R),小圆的半径(r)和两个圆之间的距离(0.5R),嘴的圆心坐标。

//嘴的半径 private var mouseRadius = 0f //小圆的半径 private var ballRadius = 0f //嘴和小球的间距 private var space = 0f //嘴的圆心 private var cx = 0f private var cy = 0f

3.在onSizeChanged方法中计算大小。

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { if(measuredWidthgt;=measuredHeight){ ballRadius= measuredHeight/6f cx = (measuredWidth-8.5f*ballRadius)/2 + 3*ballRadius }else{ ballRadius= measuredWidth/8.5f cx = 3*ballRadius.toFloat() } mouseRadius = 3*ballRadius space = ballRadius/2f cy = measuredHeight/2f }

4.提供画笔

//画笔 private val mPaint = Paint().apply { style = Paint.Style.FILL color = context.resources.getColor(R.color.colorAccent,null) }

5.用onDraw方法画一个圆

override fun onDraw(canvas: Canvas) { canvas.drawCircle(cx,cy,mouseRadius,mPaint)}

6.在xml文件中添加这个自定义类

lt;com.example.loadinganim.MouseLoadingView android:id="@+id/loadingView" android:layout_width="100dp" android:layout_height="100dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.11" /gt;

7.如果用上面的方法画圆,会出现一些bug,如下图。


这是因为,当宽度大于高度时,R=高度/6。如果r太小,那么圆心的坐标就剩了,然后有些圆就出界了。为了避免这种情况,在任何情况下都要将R设为最小的/8.5。

8.重新计算半径

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) //计算尺寸 //小球的半径 ( Math.min(measuredHeight,measuredWidth)/8.5f ).also {r-gt; ballRadius = r //嘴的半径 mouseRadius = 3*r //嘴和小球的间距 space = r/2 //嘴的圆心 cx = ((measuredWidth- 8.5*r)/2 + 3*r).toFloat() cy = measuredHeight/2f } }


四、实现张嘴闭嘴动画

1.张嘴就相当于画了一个弧线。画圆弧需要确定一个矩形区域;;也就是大圆所在的矩形。你还需要设置一个角度,也就是弧度。如下图所示画出来。

override fun onDraw(canvas: Canvas) { canvas.drawArc( cx-mouseRadius, cy-mouseRadius, cx+mouseRadius, cy+mouseRadius, 45f,270f,true,mPaint )}


image.png

2.这是一个静态过程。如果想让它有动感,只需要不断修改张嘴的角度就可以了。所以我们定义一个动画因子为弧度。

//嘴张开的角度 - gt;张嘴的动画因子 private var mouseAngle = 0f

3.然后在onDraw方法中,将死数据更改为我们的动画因子。

canvas.drawArc( cx-mouseRadius, cy-mouseRadius, cx+mouseRadius, cy+mouseRadius, mouseAngle,360-2*mouseAngle,true,mPaint )

4.添加两个按钮来显示动画和暂停动画。当按钮被点击时,相应的点击事件被实现。

5.所以在MouseLoadingView类中,为外部调用提供了几个方法。

} //提供给外部使用 //显示动画 fun show(){ createAnimator() start() } //隐藏动画 fun hide(){ stop() }

6.createAnimator()是一个创建动画的函数。从0-45-0是动画因子的变化。听动画执行的过程,不断刷新动画因子的值,然后刷新界面。

private fun createAnimator() { ValueAnimator.ofFloat(0f, 45f, 0f).apply { duration = 650 repeatCount = ValueAnimator.INFINITE addUpdateListener { mouseAngle = it.animatedValue as Float //刷新界面 invalidate() } animators.add(this) }}

7.因为有很多动画效果,所以我们要用一个数组来保存所有的动画。

//保存所有的动画对象 private var animators = mutableListOflt;ValueAnimatorgt;()

8.添加几种开始和结束动画的方法

//启动动画 private fun start(){ for(anim in animators){ anim.start() } }//暂停动画 private fun stop(){ for(anim in animators){ anim.end() }


五、小球移动动画

1.创建一个小球,然后让它从右边移动到左边。小球圆心的x坐标是不断变化的,y坐标和大圆是一样的。所以我们要为球设置一个移动的动画因子。

//小球移动的动画因子 private var ballTranslateX = 0f

2.然后在onDraw()方法中画球。

//绘制小球canvas.drawCircle(cx+ballTranslateX,cy,ballRadius,mPaint)

3.之后,在createAnimator()方法中添加球的动画。让球从4.5R移动到0,也就是直到小圆和大圆重合。

ValueAnimator.ofFloat(4.5f*ballRadius, 0f).apply { duration = 650 repeatCount = ValueAnimator.INFINITE addUpdateListener { ballTranslateX = it.animatedValue as Float //刷新界面 invalidate() } animators.add(this) }

4.在MainActivity中添加按钮click事件。

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) startBtn.setOnClickListener{ loadingView.show() pauseView.show() } stopBtn.setOnClickListener { loadingView.hide() pauseView.hide() } }}

大概就是这样。自定义动画加载的难点在于寻找动画因子。

以上是Android开发的定制加载动画的详细内容。更多安卓加载动画信息

0

精彩评论

暂无评论...
验证码 换一张
取 消