Android 动画之视图动画

732 阅读5分钟

image.png

视图动画

Android的视图动画由五种类型组成。

  • alpha 透明度。渐变透明度动画效果
  • scale 缩放。渐变尺寸伸缩动画效果
  • translate 移动。画面变换位置移动动画效果
  • rotate 旋转。画面转移旋转动画效果
  • set 以上四种集合。定义动画集

视图动画的标签实现

1、scale标签的使用

在res/anim文件夹中创建scaleanim.xml文件

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="0.0"
    android:toXScale="1.5"
    android:fromYScale="0.0"
    android:toYScale="1.5"
    android:duration="5000"
    android:pivotX="0"
    android:pivotY="0">
</scale>

通过以下的方法将该动画文件应用到一个View中。

val animation = android.view.animation.AnimationUtils.loadAnimation(this,R.anim.scaleanim)
textView.startAnimation(animation)

效果如下,可以看到顶部的view的尺寸会在左上角处,从0慢慢变大到1.5的尺寸,然后回复到初始尺寸。

scale动画.gif

可以看到scale标签可以实现动态的调整控件尺寸的效果。

  • android:fromXScale="0.0" 动画起始状态时,View在x轴上的尺寸相对于自身尺寸的缩放比例
  • android:toXScale="1.5" 动画在结束状态时,View在x轴上的尺寸相对于自身尺寸的缩放比例
  • android:fromYScale="0.0" 动画起始状态时,View在y轴上的尺寸相对于自身尺寸的缩放比例
  • android:toYScale="1.5" 动画在结束状态时,View在y轴上的尺寸相对于自身尺寸的缩放比例
  • android:duration="5000" 动画的持续时间
  • android:pivotX="0" 缩放起始点的X轴坐标,可以是数值、百分数、百分数P三种取值。
  • android:pivotY="0" 缩放起始点的Y轴坐标

最后的两个参数用于定位缩放起始点的坐标,特别说明下:

以pivotX为例,如果取值是50,表示缩放起始点的X轴坐标为View左上角的坐标加上50px。如果取值是50%,表示缩放起始点坐标为View左上角的坐标加上宽度的50%,即View宽度的中心位置是缩放起始点的X轴坐标。如果是50%p,则缩放起始点的X轴坐标为View左上角的X轴坐标加上父控件宽度的50%是起始点的X轴坐标。

比如我们将以上的xml文件修改如下,会从中间位置开始缩放。

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="0.0"
    android:toXScale="1.5"
    android:fromYScale="0.0"
    android:toYScale="1.5"
    android:duration="5000"
    android:pivotX="50%"
    android:pivotY="50%">
</scale>

Untitled.gif

其他属性设置

  • android:fillAfter 如果设置为true,会保持住动画结束时的状态,而不恢复到原样
  • android:fillBefore 如果设置为true,动画结束后,会恢复到原样
  • android:repeateCount 用于设置动画的播放次数,当取值为infinite时,会无限播放
  • android:repeateMode 用于设置重复播放的类型,有reverse和restart两种取值,reverse表示倒序播放,restart表示从头开始播放,必须与repeateCount同时使用才能看到效果。
  • android:interpolator 用于设置插值器,即指定动画效果,比如弹跳效果等。

scale动画的代码实现

val animation = ScaleAnimation(0.0f,1.5f, //X轴的起点和终点尺寸
    0.0f,1.5f, //Y轴的起点和终点尺寸
    Animation.RELATIVE_TO_SELF,0.5f, //缩放起始点的X轴坐标设置 ,等价于xml文件中的50%Animation.RELATIVE_TO_SELF,0.5f //缩放起始点的Y轴坐标设置 ,等价于xml文件中的50%。
    )
animation.duration = 5000
textView.startAnimation(animation)

以上代码可实现与xml文件相同的效果。

2、alpha标签的使用

在anim文件夹下创建如下的文件

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1"
    android:toAlpha="0"
    android:repeatCount="5"
    android:repeatMode="reverse"
    android:duration="5000">
</alpha>

可实现View由透明到不透明,然后由不透明到透明的效果。

scale.gif

其中 android:fromAlpha 表示动画开始时的透明度 android:toAlpha 表示动画结束时的透明度

以下是同等效果的代码实现

val animation = AlphaAnimation(1.0f,0.0f)
animation.duration = 5000
textView.startAnimation(animation)

3、rotate标签的使用

rotate标签用于实现view 的旋转

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="5000"
    android:fillAfter="true">
</rotate>

可实现View的旋转效果

rotate.gif

  • android:fromDegrees="0" 动画开始旋转时的角度,正数表示顺时针方向的角度,负数表示逆时针方向的角度
  • android:toDegrees="360" 动画结束时旋转到的角度位置
  • android:pivotX="50%" 动画旋转中心点的X轴坐标,取值以及含义和scale中相同
  • android:pivotY="50%" 动画旋转中心点的Y轴坐标

同等效果的代码实现

val animation = RotateAnimation(0f,360f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f)
animation.duration = 5000
textView.startAnimation(animation)

4、translate标签

translate标签用于实现View的移动

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="300"
    android:toYDelta="300"
    android:duration="5000">
</translate>

translate.gif

  • android:fromXDelta="0" 起始点X轴坐标,取值可以是数值、百分数以及百分数p三种样式,含义与scale和scale中相同
  • android:fromYDelta="0" 起始点Y轴坐标
  • android:toXDelta="300" 终点X轴坐标
  • android:toYDelta="300" 终点Y轴坐标

同等条件的代码实现

val animation = TranslateAnimation(0f,300f,0f,300f)
animation.duration = 5000
textView.startAnimation(animation)

5、set标签

set标签是一个容器类标签,可以定义一个动画集。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:fillAfter="true"
    >
    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%">
    </rotate>


    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="300"
        android:toYDelta="300">
    </translate>
</set>

以上的文件将上面的rotate和translate动画结合了起来。在set标签中的属性可对其中的所有子控件产生作用.

在set标签中设置repeatCount属性是无效的,必须对每个动画单独设置才有作用。

set.gif

以下是同等效果的代码实现

val animation3 = RotateAnimation(0f,360f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f)
val animation4 = TranslateAnimation(0f,300f,0f,300f)
val animationSet = AnimationSet(true)
animationSet.addAnimation(animation3)
animationSet.addAnimation(animation4)
animationSet.duration = 5000
animationSet.fillAfter = true
textView.startAnimation(animationSet)

动画监听

使用代码编写时,还可为动画设置监听

animationSet.setAnimationListener(object :Animation.AnimationListener{
    override fun onAnimationStart(animation: Animation?) {
        Log.d(TAG, "onAnimationStart: 动画开始")
    }

    override fun onAnimationEnd(animation: Animation?) {
        Log.d(TAG, "onAnimationEnd: 动画结束")
    }

    override fun onAnimationRepeat(animation: Animation?) {
        Log.d(TAG, "onAnimationRepeat: 动画结束")
    }
})
参考资料《Android自定义控件开发与实战》