【笔记】Android动画

前言

Android动画学习笔记

逐帧动画(frame-by-frame animation)

  • 把几张图片进行快速播放,实现的动画效果

创建图片列表xml

  • 将一组用于创建动画的图片放到/app/src/main/res/drawable/目录下

  • 创建一个用于存放图片列表的xml文件frame.xml

/app/src/main/res/drawable/frame.xml

android:drawable="@drawable/图片名":定义图片路径
android:duration="<ms>":定义图片显示时间,单位毫秒

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/图片名" android:duration="<ms>" />
...

</animation-list>

把动画添加到页面

/app/src/main/res/drawable/activity_main.xml

android:background="@drawable/frame":背景设置为刚刚定义的图像列表

1
2
3
4
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/frame" />

启动动画

/app/src/main/java/.../MainActivity.java
1
2
3
4
RelativeLayout relativeLayout = findViewById(R.id.rl);
AnimationDrawable animationDrawable = (AnimationDrawable) relativeLayout.getBackground();

animationDrawable.start();

停止动画

/app/src/main/java/.../MainActivity.java
1
2
3
4
RelativeLayout relativeLayout = findViewById(R.id.rl);
AnimationDrawable animationDrawable = (AnimationDrawable) relativeLayout.getBackground();

animationDrawable.stop();

补间动画(tweened animation)

  • 给动画设置一个初始图、结束图、动画时间,安卓自动补全动画

图片放到页面

/app/src/main/res/drawable/activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/图片名" />

</LinearLayout>

设置动画配置文件

  • /app/src/main/res/目录下创建anim目录,用于存放xml动画配置文件

透明度

  • /app/src/main/res/anim/目录下创建alpha.xml文件用于配置透明度动画

android:duration="":动画持续时间,单位毫秒
android:fromAlpha="":动画开始时的透明度,取值范围:[0,1]
android:toAlpha="":动画结束时的透明度,取值范围:[0,1]

/app/src/main/res/anim/alpha.xml
1
2
3
4
5
6
7
8
<set xmlns:android="http://schemas.android.com/apk/res/android">

<alpha
android:duration=""
android:fromAlpha="0"
android:toAlpha="1" />

</set>

旋转

  • /app/src/main/res/anim/目录下创建rotate.xml文件用于配置旋转动画

android:duration="":动画持续时间,单位毫秒
android:fromDegrees="":动画开始时的角度,取值范围:[0,360]
android:toDegrees="":动画结束时的角度,取值范围:[0,360]
android:pivotX="":旋转中心点的横坐标位置,取值范围:[0%,100%]
android:pivotY="":旋转中心点的纵坐标位置,取值范围:[0%,100%]

/app/src/main/res/anim/rotate.xml
1
2
3
4
5
6
7
8
9
10
<set xmlns:android="http://schemas.android.com/apk/res/android">

<rotate
android:duration=""
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%" />

</set>

缩放

  • /app/src/main/res/anim/目录下创建scale.xml文件用于配置缩放动画

android:duration="":动画持续时间,单位毫秒
android:fromXScale="":动画开始时的横向缩放倍数
android:fromYScale="":动画开始时的纵向缩放倍数
android:toXScale="":动画结束时的横向缩放倍数
android:toYScale="":动画结束时的纵向缩放倍数
android:pivotX="":缩放中心点的横坐标位置,取值范围:[0%,100%]
android:pivotY="":缩放中心点的纵坐标位置,取值范围:[0%,100%]

/app/src/main/res/anim/scale.xml
1
2
3
4
5
6
7
8
9
10
11
12
<set xmlns:android="http://schemas.android.com/apk/res/android">

<scale
android:duration=""
android:fromXScale=""
android:fromYScale=""
android:toXScale=""
android:toYScale=""
android:pivotX="50%"
android:pivotY="50%" />

</set>

平移

  • /app/src/main/res/anim/目录下创建translate.xml文件用于配置平移动画

android:duration="":动画持续时间,单位毫秒
android:fromXDelta="":动画开始时的位置横坐标
android:fromYDelta="":动画开始时的位置纵坐标
android:toXDelta="":动画结束时的位置横坐标
android:toYDelta="":动画结束时的位置纵坐标

/app/src/main/res/anim/translate.xml
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate
android:duration=""
android:fromXDelta=""
android:fromYDelta=""
android:toXDelta=""
android:toYDelta="" />

</set>

启动动画

/app/src/main/java/.../MainActivity.java
1
2
3
ImageView imageView = findViewById(R.id.iv);
Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.动画配置名);
imageView.startAnimation(animation);

属性动画(property animation)

  • 改变控件某一个属性,从而时间动画效果

ValueAnimator

  • 改变控件的value值

ValueAnimator.ofFloat(<start>f, <end>f):获取对象,并设置变化起止值,of后可以设置不同的数据类型
valueAnimator.setDuration(<ms>):设置动画持续时间,单位毫秒
animator.getAnimatedValue():获取变化过程中的值

/app/src/main/java/.../MainActivity.java
1
2
3
4
5
6
7
8
9
10
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.setDuration(<ms>);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
float value = (float) animator.getAnimatedValue();
...
}
});
valueAnimator.start();

ObjectAnimator

  • 改变控件对象某一属性的值

ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f):获取对象,并设置变化起止值,of后可以设置不同的数据类型

imageView:设置动画的控件对象
alpha:设置动画的控件属性,只要对象中有对应属性的get/set方法,就可以对这个属性添加动画
0f:开始值
1f:截止值

valueAnimator.setDuration(<ms>):设置动画持续时间,单位毫秒

/app/src/main/java/.../MainActivity.java
1
2
3
4
5
ImageView imageView = findViewById(R.id.iv);

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1f);
objectAnimator.setDuration(<ms>);
objectAnimator.start();

设置监听器

/app/src/main/java/.../MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
objectAnimator.addListener(new Animator.AnimatorListener() {
// 监听启动状态
@Override
public void onAnimationStart(Animator animator) {

}

// 监听结束状态
@Override
public void onAnimationEnd(Animator animator) {

}

// 监听取消状态
@Override
public void onAnimationCancel(Animator animator) {

}

// 监听重复状态
@Override
public void onAnimationRepeat(Animator animator) {

}
});

设置适配器

  • 适配器可以只重写一个监听方法
/app/src/main/java/.../MainActivity.java
1
2
3
objectAnimator.addListener(new AnimatorListenerAdapter() {
...
});

完成

参考文献

哔哩哔哩——Android架构解析