Android
中动画分为早期的 Animation
(视图动画) 和 Android 3.0
增加的 Animator
(属性动画)。这里主要记录 Animation
的使用方法。
一、Animation
Animation
二、FrameAnimation
(逐帧动画)
FrameAnimation
就是通过逐帧播放来实现的动画。
使用步骤:
- 在
res/drawable
文件夹下新建animation-list
的XML
;
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<!-- animation-list 帧动画 -->
<!-- android:oneshot的值为 false代表播放多次,true代表只播放一次 -->
<!-- duration代表每张图片的播放时间 ,定义一个持续时间为50毫秒的动画帧 -->
<item
android:drawable="@drawable/loading_1"
android:duration="50" />
<item
android:drawable="@drawable/loading_2"
android:duration="50" />
<item
android:drawable="@drawable/loading_3"
android:duration="50" />
<item
android:drawable="@drawable/loading_4"
android:duration="50" />
<item
android:drawable="@drawable/loading_5"
android:duration="50" />
<item
android:drawable="@drawable/loading_6"
android:duration="50" />
<item
android:drawable="@drawable/loading_7"
android:duration="50" />
<item
android:drawable="@drawable/loading_8"
android:duration="50" />
<item
android:drawable="@drawable/loading_9"
android:duration="50" />
<item
android:drawable="@drawable/loading_10"
android:duration="50" />
<item
android:drawable="@drawable/loading_11"
android:duration="50" />
<item
android:drawable="@drawable/loading_12"
android:duration="50" />
<item
android:drawable="@drawable/loading_13"
android:duration="50" />
<item
android:drawable="@drawable/loading_14"
android:duration="50" />
<item
android:drawable="@drawable/loading_15"
android:duration="50" />
<item
android:drawable="@drawable/loading_16"
android:duration="50" />
<item
android:drawable="@drawable/loading_17"
android:duration="50" />
<item
android:drawable="@drawable/loading_18"
android:duration="50" />
<item
android:drawable="@drawable/loading_19"
android:duration="50" />
<item
android:drawable="@drawable/loading_20"
android:duration="50" />
</animation-list>
- 添加控件,设置
background
;
直接在 XML
中声明背景图片:
<ImageView
android:id="@+id/iv_loading"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:background="@drawable/loading_anim_layout"/>
也可以动态设置背景图片:
mIvLoading = findViewById(R.id.iv_loading);
AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.loading_anim_layout);
mIvLoading.setBackground(animationDrawable);
- 开启和关闭帧动画;
设置完背景图片后,需要调用动画启动的函数,不然默认只会停留在第一帧处。
如:
((AnimationDrawable)mIvLoading.getBackground()).start();
//stop() 停止播放
- 第一步中设置帧也可以直接在代码中添加;
private void setFrameAnimation() {
AnimationDrawable animationDrawable = new AnimationDrawable();
//为AnimationDrawable添加动画帧
animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_1), 50);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_2), 50);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_3), 50);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.loading_4), 50);
//...
// 设置为循环播放
animationDrawable.setOneShot(true);
mIvLoading.setBackground(animationDrawable);
}
三、TweenAnimation
补间动画
Tween
动画是通过对 View
进行一些列的图像变换,包括平移、缩放、旋转、透明度变化,从而达到动画效果。
Tween
动画并不改变 View
的属性,只是改变了 View
绘制的位置,没有改变 View
对象本身。比如屏幕左上角的一个空间,通过补间动画平移到右上角后,其点击区域还是在左上角。
实现补帧动画有两种方式,XML
中声明和直接代码两种方式。
(1) AlphaAnimation
(透明度)
-
XML
方式实现:
在res/anim/
目录下添加XML
文件
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fillAfter="false"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
-
fromAlpha
: 开始时透明度,0
是完全透明,1
是完全不透明; -
toAlpha
: 结束时透明度,0
是完全透明,1
是完全不透明; -
duration
: 动画持续时间,单位毫秒; -
fillAfter
:动画结束后是否停留在最后一帧。默认false
; -
fillBefore
:动画结束后是否停留在第一帧。默认true
。和fillAfter
同时设置则只会看fillAfter
; -
fillEnbabled
: 与android:fillBefore
效果相同? -
interpolator
: 指定插值器
获取动画并设置给对应的 View
:
Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_alpha);
mIvLoading.startAnimation(alphaAnimation);
- 代码实现方式:
Animation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
alphaAnimation.setDuration(500);//设置动画持续时间为500毫秒
alphaAnimation.setFillAfter(false);//设置动画结束后保持当前的位置(即不返回到动画开始前的位置)
mIvLoading.startAnimation(alphaAnimation);
(2) ScaleAnimation
(缩放)
-
XML
实现方式:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:toXScale="1.0"
android:toYScale="1.0" />
-
fromXScale
,fromYScale
: 动画开始前X,Y的缩放,0.0
为不显示,1.0
为正常大小; -
toXScale
,toYScale
: 动画最终缩放的倍数,1.0
为正常大小,大于1.0
放大,小于1.0
缩小;
还可以设置:
-
pivotX
,pivotY
: 动画起始位置,相对于自身的百分比,两个都为50%
表示动画从自身中间开始; -
repeatCount
: 动画重复的计数,动画将会执行该值+1
次; -
repeatMode
: 动画重复的模式,reverse
为反向,当第偶次执行时,动画方向会相反。restart
为重新执行,方向不变; -
startOffset
: 动画多次执行的间隔时间,如果只执行一次,执行前会暂停这段时间,单位毫秒; -
fromXDelta
,fromYDelta
: 起始时X
,Y
座标; -
toXDelta
,toYDelta
: 动画结束时X
,Y
的座标;
获取动画并设置给对应的 View
:
Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_scale);
mIvLoading.startAnimation(scaleAnimation);
- 代码实现方式:
Animation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(1000);
scaleAnimation.setRepeatCount(3);//设置动画循环次数
scaleAnimation.setRepeatMode(Animation.REVERSE);
scaleAnimation.setStartOffset(0);
scaleAnimation.setInterpolator(this, android.R.anim.decelerate_interpolator);//设置动画插入器
mIvLoading.startAnimation(scaleAnimation);
(3) RotateAnimation
(旋转)
-
XML
实现方式:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
-
fromDegrees
: 动画开始时的角度; -
toDegrees
: 动画结束时的角度,为正顺时针旋转,为负逆时针旋转;
获取动画并设置给对应的 View
:
Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_rotate);
mIvLoading.startAnimation(rotateAnimation);
- 代码实现方式:
Animation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(1000);
rotateAnimation.setFillAfter(true);
mIvLoading.startAnimation(rotateAnimation);
(4) TranslateAnimation
(平移)
-
XML
实现方式:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="100"
android:toYDelta="100" />
-
fromXDelta
,fromYDelta
: 起始时X
,Y
座标; -
toXDelta
,toYDelta
: 动画结束时X
,Y
的座标;
获取动画并设置给对应的 View
:
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_translate);
mIvLoading.startAnimation(translateAnimation);
- 代码实现方式:
Animation translateAnimation = new TranslateAnimation(0, 0, 100, 100);
translateAnimation.setDuration(1000);
mIvLoading.startAnimation(translateAnimation);
(5) AnimationSet
(动画集合)
XML
实现方式:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<!-- 各种单独特效的杂糅 -->
<alpha
android:duration="1000"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
<rotate
android:duration="1000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="720" />
<scale
android:duration="1000"
android:fromXScale="0.1"
android:fromYScale="0.1"
android:toXScale="1.0"
android:toYScale="1.0" />
<translate
android:duration="1000"
android:fillAfter="true"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="100"
android:toYDelta="100" />
</set>
获取动画并设置给对应的 View
:
Animation animationSet = AnimationUtils.loadAnimation(this, R.anim.tween_anim_set);
mIvLoading.startAnimation(animationSet);
代码方式实现:
AnimationSet animationSet = new AnimationSet(true);
Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_alpha);
Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_scale);
Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_rotate);
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim_translate);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(translateAnimation);
mIvLoading.startAnimation(animationSet);
四、动画监听器
有时,我们需要知道动画的一些状态,然后在不同的周期做相应的操作,这时可以使用动画监听器,如下:
animationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//动画开始时调用
}
@Override
public void onAnimationEnd(Animation animation) {
//动画结束时调用
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重复时调用
}
});
网友评论