视图动画
视图动画 包含 补间动画(Tween Animation)
与 逐帧动画(Frame Animation)
1. 补间动画(Tween Animation)
XML实现 | 代码实现 |
---|---|
alpha 透明度动画 | AlphaAnimation |
scale 缩放动画 | ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) |
translate 移动动画 | TranslateAnimation |
rotate 旋转动画 | RotateAnimation |
set 动画集合 | AnimationSet |
// 代码实现
TranslateAnimation translateAnim = new TranslateAnimation(0, 300, 0, -50);
translateAnim.setFillAfter(true);
translateAnim.setDuration(1000);
view.startAnimation(translateAnim);
透明的效果
看看XML的DEMO
// XML实现 => res/anim/translate_anim.xml
// 动画集合 set,包含了 alpha(透明) + rotate(旋转)
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000">
// 透明度 0.0 ~ 1.0 的过渡
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
// 旋转(以中心旋转(0~720)
<rotate
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="720" />
</set>
// 在代码中进行设置 xml 动画文件
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
view.startAnimation(animation);
// 代码翻译XML
AnimationSet set = new AnimationSet(true);
set.addAnimation(new AlphaAnimation(...));
set.addAnimation(new RotateAnimation(...));
set.setDuration(3000);
view.startAnimation(set);
几个属性的含义
XML标签属性 | 代码属性 | 含义 |
---|---|---|
android:duration | setDuration(long) | 时间,毫秒,动画执行的时间 |
android:fillAfter | setFillAfter(boolean) | 如果为true,动画结束,保持结束时的状态 |
android:fillBefore | setFillBefore(boolean) | 如果为true,动画结束,恢复到初开始的状态 |
android:fillEnabled | setFillEnable(boolean) | 同setFillBefore类似,都是动画结束,恢复最初状态 |
android:repeatCount | setRepeatCount(int) | 动画重复次数(大于等于 0),值为 小于0 或 Animation.INFINITE 时,无限循环 |
android:repeatMode | setRepeatMode(int) | 动画重复的类型 reverse(倒序回放), restart(从新开始),必须与 repeatCount一起使用,才有效果 |
android:interpolator | setInterpolator(Interpolator) | 插值器(在属性动画的章节中一起讲解) |
// 以 中间的位置 进行 缩放(1.0 ~ 1.2 ~ 1.0 ~ 1.2) 动画
ScaleAnimation scaleAnim = new ScaleAnimation(
1.0f, 1.2f, 1.0f, 1.2f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
其它相关属性
ScaleAnimation,AlphaAnimation 等 继承Animation,Animation 除了提供上面相关的函数外,
还提供了 cancel()取消动画
,reset()将控件恢复到动画开始前的状态
还可以设置动画相关的监听 Animation.setAnimationListener(new Animation.AnimationListener() { ... Start ... End ... }
AnimationListener 的 回调包含如下几个:
onAnimationStart(Animation animation)
动画开始时onAnimationEnd(Animation animation)
动画结束时onAnimationRepeat(Animation animation)
动画重复时,一般设置了 repeatCount 的重复次数,才会触发
// 示例代码
translateAnim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
场景小剧场
有一个小场景,是我们公司的 一个 HDMI信号界面,就是这种水波纹,还有一些信号覆盖的也有类似的动画效果… …
还有界面上看到的一些进度条爱的魔力转圈圈,比如
还有我们看到的一些应用的过渡效果。
当然,使用的场景很多,这里只是列举几个… …
2. 逐帧动画(Frame Animation)
通俗的理解就是,一帧挨一帧地播放图片,就像放电影/动画片一样,可以通过XML实现,也可以通过代码实现;
XML实现
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" | "true">
<item android:drawable="@drawable/img000001" android:duration="60(integer)"/>
... ...
</animation-list>
android:oneshot
如果定义为 true,动画只执行一次,反之,一直循环android:drawable
指定此帧动画的图片资源android:duration
帧动画持续的时间,整数,单位毫秒ms
举个栗子(XML):
# playing_test_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/img000001" android:duration="60"/>
<item android:drawable="@drawable/img000002" android:duration="60"/>
... ...
</animation-list>
# 布局 xml 文件
<ImageView android:src="@drawable/playing_test_anim"/>
# 代码执行
AnimationDrawable animDrawable = (AnimationDrawable) imageView.getDrawable();
animDrawable.start();
AnimationDrawable 几个常用函数
函数名称 | 含义 |
---|---|
start | 开始播放 |
stop | 停止播放 |
int getDuration(int index) | 得到指定 index 帧的时间 |
Drawable getFrame(int index) | 得到指定 index 帧对应的 Drawable 对象 |
int getNumberOfFrames() | 获取 所有帧的数量 |
boolean isRunning() | 是否正在播放 |
setOneShot(boolean oneShot) | true 执行一次,false 循环播放 |
boolean isOneShot() | 返回 true 执行一次,返回 false 循环播放 |
addFrame(Drrawable frame, int duration) | 添加一帧,并设置持续时间 |
代码实现
关键函数:addFrame(Drrawable frame, int duration)
举个小栗子(代码):
final AnimationDrawable animationDrawable = new AnimationDrawable();
for (int i = 1; i < 28; i++) {
int id = getResources().getIdentifier("img00000" + i, "drawable", getPackageName());
Drawable drawable = getResources().getDrawable(id);
animationDrawable.addFrame(drawable, 60);
}
animationDrawable.setOneShot(false);
imageView.setImageDrawable(animationDrawable);
animationDrawable.start();
场景小剧场
帧动画 会在 制作 较为复杂的个性化动画效果 出现,比如 引导动画,还有类似的开机动画 等等
小总结
Frame Animation(逐帧动画)相对来说
优点:
比较简单(使用简单、方便),实际开发中使用的频率还是比较高的。
缺点:
一方面是因为会造成OOM,另一方面会显得很卡,另另一方面也是资源图片也会很多;如果复杂而且帧数比较多的动画不太建议使用逐帧动画
现在 技术上 层出不穷,已经出现了很多可以替代的方案,比如 SVG动画
,Lottie库
等。
参考资料
Android动画了解—为什么需要动画<=上个章节 下个章节=> Android动画了解—属性动画(Property Animation)