Android动画总结
Posted AC_Jobim
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android动画总结相关的知识,希望对你有一定的参考价值。
Android动画目前分为三种:
- Tween Animation 补间动画(又叫view动画),是通过对场景里的对象不断做图像变换(透明度、缩放、平移、旋转)从而产生动画效果,是一种渐进式动画,并且View动画支持自定义。
- Frame Animation 帧动画,通过顺序播放一系列图像从而产生动画效果,图片过多时容易造成OOM(Out Of Memory内存用完)异常。
- Property Animation 属性动画,这也是在android3.0之后引进的动画,在手机的版本上是android4.0就可以使用这个动画,通过动态的改变对象的属性从而达到动画效果。
补间动画和属性动画的区别:
补间动画只是改变了View的显示效果而已,并不会真正的改变View的属性。而属性动画可以改变View的显示效果和属性。举个例子:例如屏幕左上角有一个Button按钮,使用补间动画将其移动到右下角,此刻你去点击右下角的Button,它是绝对不会响应点击事件的,因此其作用区域依然还在左上角。只不过是补间动画将其绘制在右下角而已,而属性动画则不会。
一、View动画(Tween Animation也称补间动画)
View动画的分类:
单一动画:
复合动画(AnimationSet):由多个单一动画组合在一起的动画
动画相关的操作:
Animation的公用方法:
- setDuration(long durationMillis) : 设置持续时间(单位ms)
- setStartOffset(long startOffset) : 设置开始的延迟的时间(单位ms)
- setFillBefore(boolean fillBefore) : 设置最终是否固定在起始状态
- setFillAfter(boolean fillAfter) : 设置最终是否固定在最后的状态
- setAnimationListener(AnimationListener listener) : 设置动画监听
坐标类型:
- Animation.ABSOLUTE 绝对坐标
- Animation.RELATIVE_TO_SELF 相对于自己坐标
- Animation.RELATIVE_TO_PARENT 相对于父容器坐标
动画的启动和结束:
- 启动动画 : view.startAnimation(animation);
- 结束动画: view.clearAnimation()
动画监听器 : AnimationListener
- onAnimationStart(Animation animation) : 动画开始的回调
- onAnimationEnd(Animation animation) : 动画结束的回调
- onAnimationRepeat(Animation animation) : 动画重复执行
注意:动画效果有一个很大的问题,就是当移动到指定位置后,点击该位置是无效的,只能点击原来的位置才有效,它并不是真的移动到该位置了,可以通过属性动画来解决。
1.1 ScaleAnimation(缩放动画)
效果展示:
java代码实现:
/*
* 1.1 编码实现: 缩放动画
* ScaleAnimation
*/
public void startCodeScale(View v) {
tv_animation_msg.setText("Code缩放动画: 宽度从0.5到1.5, 高度从0.0到1.0, 缩放的圆心为顶部中心点,延迟1s开始,持续2s,最终还原");
//1. 创建动画对象
ScaleAnimation animation = new ScaleAnimation(0.5f,0.5f,0.0f,1f,
Animation.ABSOLUTE,iv_animation.getWidth()/2,Animation.ABSOLUTE,0);
//或者
animation = new ScaleAnimation(0.5f, 1.5f, 0, 1,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0);
//2. 设置
//延迟1s开始
animation.setStartOffset(1000);
//持续2s
animation.setDuration(2000);
//最终还原
animation.setFillBefore(true);
//3. 启动动画
iv_animation.startAnimation(animation);
}
xml实现:
- fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例
- toXScale/toYScale:沿着X轴/Y轴缩放的结束比例
- pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的中心为中轴点。
以 pivotX 为例,其取不同的值的含义:
- 10:距离动画所在view自身左边缘10像素
- 10% :距离动画所在view自身左边缘 的距离是整个view宽度的10%
- 10%p:距离动画所在view父控件左边缘的距离是整个view宽度的10%
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0"
android:fromYScale="0"
android:toXScale="1.5"
android:toYScale="1"
android:startOffset="1000"
android:duration="3000"
android:pivotX="100%"
android:pivotY="100%"
android:fillAfter="true">
</scale>
<!-- 宽度从0.0到1.5, 高度从0.0到1.0, 延迟1s开始,持续3s,圆心为右下角, 最终固定 -->
/*
* 1.2 xml实现: 缩放动画
* <scale>
*/
public void startXmlScale(View v) {
tv_animation_msg.setText("Xml缩放动画: Xml缩放动画: 宽度从0.0到1.5, 高度从0.0到1.0, 延迟1s开始,持续3s,圆心为右下角, 最终固定");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
1.2 RotateAnimation(旋转动画)
效果展示:
java代码实现:
/*
* 2.1 编码实现: 旋转动画
* RotateAnimation
*/
public void startCodeRotate(View v) {
tv_animation_msg.setText("Code旋转动画: 以图片中心点为中心, 从负90度到正90度, 持续5s");
//1. 创建动画对象
RotateAnimation animation = new RotateAnimation(-90, 90, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
//2. 设置
animation.setDuration(5000);
//3. 启动动画
iv_animation.startAnimation(animation);
}
xml实现:
- fromDegrees/toDegrees:旋转的起始/结束角度
- repeatCount:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止
- repeatMode:设置重复模式,默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动!
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="90"
android:toDegrees="-90"
android:duration="5000">
</rotate>
<!-- 以左顶点为坐标, 从正90度到负90度, 持续5s -->
/*
* 2.2 xml实现: 旋转动画
* <rotate>
*/
public void startXmlRotate(View v) {
tv_animation_msg.setText("Xml旋转动画: 以左顶点为坐标, 从正90度到负90度, 持续5s");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
1.3 AlphaAnimation(透明度渐变动画)
效果展示:
java代码实现:
/*
* 3.1 编码实现: 透明度动画
* 完全透明 : 0
* 完全不透明 : 1
* AlphaAnimation
*/
public void startCodeAlpha(View v) {
tv_animation_msg.setText("Code透明度动画: 从完全透明到完全不透明, 持续4s");
//1. 创建动画对象
AlphaAnimation animation = new AlphaAnimation(0, 1);
// 2. 设置
animation.setDuration(4000);
// 3. 启动动画
iv_animation.startAnimation(animation);
}
xml实现:
- fromAlpha :起始透明度
- toAlpha:结束透明度
- 透明度的范围为:0-1,完全透明-完全不透明
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1"
android:toAlpha="0"
android:duration="4000">
</alpha>
<!-- 从完全不透明到完全透明, 持续4s -->
/*
* 3.2 xml实现: 透明度动画
* <alpha>
*/
public void startXmlAlpha(View v) {
tv_animation_msg.setText("Xml透明度动画: 从完全不透明到完全透明, 持续4s");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_test);
// animation.setFillAfter(true);
//3. 启动动画
iv_animation.startAnimation(animation);
}
1.4 TranslateAnimation(平移动画)
效果展示:
java代码实现:
/*
* 4.1 编码实现: 平移动画
* TranslateAnimation
*/
public void startCodeTranslate(View v) {
tv_animation_msg.setText("Code移动动画: 向右移动一个自己的宽度, 向下移动一个自己的高度, 持续2s");
//1. 创建动画对象
TranslateAnimation animation = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 1, Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 1);
//2. 设置
animation.setDuration(2000);
//3. 启动动画
iv_animation.startAnimation(animation);
}
xml实现:
- fromXDelta/fromYDelta:动画起始位置的X/Y坐标
- toXDelta/toYDelta:动画结束位置的X/Y坐标
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100%p"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="0"
android:duration="2000">
</translate>
<!-- 从屏幕的右边逐渐回到原来的位置, 持续2s -->
/*
* 4.2 xml实现: 平移动画
* <translate>
*/
public void startXmlTranslate(View v) {
tv_animation_msg.setText("xml移动动画: 从屏幕的右边逐渐回到原来的位置, 持续2s"); //***此效果用于界面切换的动画效果
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
1.5 AnimationSet(组合动画)
可以使用AnimationSet把View动画的平移、缩放、旋转、渐变都揉在一起,也是既能通过代码实现,也可以通过xml实现
效果展示:
java代码实现:
/*
* 5.1 编码实现: 复合动画
* AnimationSet
*/
public void startCodeAnimationSet(View v) {
tv_animation_msg.setText("Code复合动画: 透明度从透明到不透明, 持续2s, 接着进行旋转360度的动画, 持续1s");
//1. 创建透明动画并设置
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(2000);
//2. 创建旋转动画并设置
RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(1000);
rotateAnimation.setStartOffset(2000);//延迟
//3. 创建复合动画对象
AnimationSet animationSet = new AnimationSet(true);
//4. 添加两个动画
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);
//5. 启动复合动画对象
iv_animation.startAnimation(animationSet);
}
xml实现:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000">
</alpha>
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:duration="2000"
android:startOffset="2000">
</rotate>
</set>
<!-- 透明度从透明到不透明, 持续2s, 接着进行旋转360度的动画, 持续2s -->
/*
* 5.2 xml实现: 复合动画
* <set>
*/
public void startXmlAnimationSet(View v) {
tv_animation_msg.setText("Xml复合动画: 透明度从透明到不透明, 持续2s, 接着进行旋转360度的动画, 持续2s");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = AnimationUtils.loadAnimation(this, R.anim.set_test);
//3. 启动动画
iv_animation.startAnimation(animation);
}
1.6 Interpolator属性的使用
Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复)等。
用来控制动画的变化速度,可以理解成动画渲染器,当然我们也可以自己实现Interpolator 接口,自行来控制动画的变化速度,而Android中已经为我们提供了几个个可供选择的实现类:
- LinearInterpolator:动画以均匀的速度改变
- AccelerateInterpolator:在动画开始的地方改变速度较慢,然后开始加速
- AccelerateDecelerateInterpolator:在动画开始、结束的地方改变速度较慢,中间时加速
- CycleInterpolator:动画循环播放特定次数,变化速度按正弦曲线改变: Math.sin(2 * mCycles * Math.PI * input)
- DecelerateInterpolator:在动画开始的地方改变速度较快,然后开始减速
- AnticipateInterpolator:反向,先向相反方向改变一段再加速播放
- AnticipateOvershootInterpolator:开始的时候向后然后向前甩一定值后返回最后的值
- BounceInterpolator: 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
- OvershottInterpolator:回弹,最后超出目的值然后缓慢改变到目的值
而这个东东,我们一般是在写动画xml文件时会用到,属性是:android:interpolator, 而上面对应的值是:@android:anim/linear_interpolator,其实就是驼峰命名法变下划线而已 AccelerateDecelerateInterpolator对应:@android:anim/accelerate_decelerate_interpolator!
例:
//设置线性变化
animation.setInterpolator(new LinearInterpolator());
1.7 动画的监听
/*
* 6. 测试动画监听
*/
public void testAnimationListener(View v) {
tv_animation_msg.setText("测试动画监听");
//1. 定义动画文件
//2. 加载动画文件得到动画对象
Animation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(1000);
//设置线性变化
animation.setInterpolator(new LinearInterpolator());
//设置动画重复次数
animation.setRepeatCount(3);//重复3次,Animation.INFINITE表示无限次重复
//设置动画监听
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.e("TAG", "动画开始");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.e("TAG", "动画重复");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.e("TAG", "动画结束");
}
});
//3. 启动动画
iv_animation.startAnimation(animation);
}
1.8 场景使用
1.8.1 实现登陆失败的抖动效果
效果展示:
登陆按钮的点击事件:
public void login(View v) {
//得到输入框的文本
String name = et_main_name.getText().toString();
//判断是否是空串, 如果为空串, 显示抖动动画
if("".equals(name.trim())) {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.shake);
et_main_name.startAnimation(animation);
} else {
//否则, 提示登陆
Toast.makeText(this, "去登陆", Toast.LENGTH_SHORT).show();
}
}
shank.xml:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromXDelta="0"
android:interpolator="@anim/cycle_3"
android:toXDelta="10" />
cycle_3.xml
<?xml version="1.0" encoding="utf-8"?>
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:cycles="3" />
1.8.2 activity的切换动画
显示效果:
Activity有默认的切换效果,但是我们可以定制,主要用到overridePendingTransition(int enterAnima, int exitAnima)这个方法:
startActivity(new Intent(this, SetupGuide3Activity.class));
overridePendingTransition(R.anim.right_in, R.anim.left_out);
right_in.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100%"
android:toXDelta="0"
android:duration="500">
</translate>
left_out.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="-100%"
android:duration="500">
</translate>
注意, 这个方法必须在startActivity或者finish方法之后调用才会生效
1.8.3 自定义水平进度条
效果展示:
以上是关于Android动画总结的主要内容,如果未能解决你的问题,请参考以下文章
Android使用片段在viewpager中的页面滚动上放置动画
如何在Android中加载带有动画的cardview GridView?