Android 基本动画(帧动画/补间动画/属性动画)
本文由 Luzhuo 编写,转发请保留该信息.
原文:
(Drawable Animation)帧动画
- xml文件(存于
drawable
目录下)
<?xml version="1.0" encoding="utf-8"?>
<!-- oneshot:true播放一次, false播放多次 -->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<!-- drawable:图片, duration:显示时长 -->
<item android:drawable="@drawable/girl_1" android:duration="200" />
<item android:drawable="@drawable/girl_2" android:duration="200" />
<item android:drawable="@drawable/girl_3" android:duration="200" />
<item android:drawable="@drawable/girl_4" android:duration="200" />
<item android:drawable="@drawable/girl_5" android:duration="200" />
<item android:drawable="@drawable/girl_6" android:duration="200" />
<item android:drawable="@drawable/girl_7" android:duration="200" />
<item android:drawable="@drawable/girl_8" android:duration="200" />
<item android:drawable="@drawable/girl_9" android:duration="200" />
<item android:drawable="@drawable/girl_10" android:duration="200" />
<item android:drawable="@drawable/girl_11" android:duration="200" />
</animation-list>
- 代码
/**
* 帧动画 Drawable Animation
* <br>加载一系列图片资源
*/
public void onclick1(View view){
// 设置动画图片
imageView.setBackgroundResource(R.drawable.frameanim);
// 获取动画图片
AnimationDrawable anim = (AnimationDrawable) imageView.getBackground();
anim.start(); // 执行动画
}
View Animation(补间动画)
补间动画效果不会改变控件的真实坐标
重复类型: REVERSE倒序回放 / RESTART从头播放
位置模式: ABSOLUTE(绝对像素) / RELATIVE_TO_SELF(相对于自己) / RELATIVE_TO_PARENT(相对于父控件)
代码实现
代码实现动画
/**
* 透明
*/
public void onclick1(View view){
// 透明动画 [0, 1]
AlphaAnimation aa = new AlphaAnimation(1.0f, 0.0f);
aa.setDuration(2000); // 持续时间(毫秒)
aa.setRepeatCount(0); // 重复次数: [0,+] / NFINITE(一直重复)
aa.setRepeatMode(Animation.RESTART); // 重复类型: REVERSE倒序回放 / RESTART从头播放
aa.setFillAfter(true); // 保持动画最后状态
imageView.startAnimation(aa); // 执行动画
}
/**
* 旋转
*/
public void onclick2(View view){
// 旋转动画 (参数: 开始角度, 结束角度, x位置模式, x比值, y位置模式, y比值) 位置模式: ABSOLUTE(绝对像素) / RELATIVE_TO_SELF(相对于自己) / RELATIVE_TO_PARENT(相对于父控件)
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
ra.setDuration(2000);
ra.setRepeatCount(1);
ra.setRepeatMode(Animation.RESTART);
imageView.startAnimation(ra);
}
/**
* 缩放
*/
public void onclick3(View view){
// 缩放动画 (参数:起始缩放比x, 结束缩放比x, 起始缩放比y, 结束缩放比y, x位置模式, x比值, y位置模式, y比值)
ScaleAnimation sa = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(2000);
sa.setRepeatCount(1);
sa.setRepeatMode(Animation.REVERSE);
imageView.startAnimation(sa);
}
/**
* 位移
*/
public void onclick4(View view){
// 位移动画 (参数:x起始位置模式, x起始比, x结束位置模式, x结束比, y起始位置模式, y起始比, y结束位置模式, y结束比)
TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.2f);
ta.setDuration(2000);
ta.setFillAfter(true);
imageView.startAnimation(ta);
}
/**
* 组合动画
*/
public void onclick5(View view){
// 动画集
AnimationSet set = new AnimationSet(false);
// 透明动画
AlphaAnimation aa = new AlphaAnimation(1.0f, 0.0f);
aa.setDuration(2000);
// 旋转动画
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
ra.setDuration(2000);
// 缩放动画
ScaleAnimation sa = new ScaleAnimation(1.0f,2.0f, 1.0f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(2000);
// 位移动画
TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.2f);
ta.setDuration(2000);
// 添加动画
set.addAnimation(aa);
set.addAnimation(ra);
set.addAnimation(sa);
set.addAnimation(ta);
set.setFillAfter(true);
// 一起执行
imageView.startAnimation(set);
}
xml实现
可将动画放入xml文件
- xml文件(存于
anim
目录下)
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="reverse"
android:fillAfter="true"/>
<?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="2000"
android:repeatCount="1"
android:repeatMode="reverse"/>
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="2.0"
android:toYScale="2.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="reverse"/>
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%p"
android:fromYDelta="0%p"
android:toXDelta="0%p"
android:toYDelta="20%p"
android:duration="2000"
android:fillAfter="true"/>
<?xml version="1.0" encoding="utf-8"?>
<set>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="reverse"
android:fillAfter="true"/>
<!-- ... -->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%p"
android:fromYDelta="0%p"
android:toXDelta="0%p"
android:toYDelta="20%p"
android:duration="2000"
android:fillAfter="true"/>
</set>
- 代码
/**
* 透明
*/
public void onclick1(View view){
Animation aa = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.alpha);
imageView.startAnimation(aa);
}
// 其他代码相同, 略
(Property Animation)属性动画
属性动画效果会改变控件的真实坐标
代码实现
代码实现动画
/**
* 透明
*/
public void onclick1(View view){
// alpha 参数(目标, 属性动画名, 参数...)
ObjectAnimator aa = ObjectAnimator.ofFloat(imageView, "alpha", 0,1,0,1,0,1); // 透明度[0,1]
aa.setDuration(2000);
aa.setRepeatCount(1);
aa.setRepeatMode(ObjectAnimator.RESTART);
aa.start();
}
/**
* 旋转
*/
public void onclick2(View view){
// rotation(旋转) / rotationX(X轴翻转) / rotationY(Y轴翻转)
ObjectAnimator ra = ObjectAnimator.ofFloat(imageView, "rotationX", 0,180,90,360); // 角度
ra.setDuration(2000);
ra.start();
}
/**
* 缩放
*/
public void onclick3(View view){
// scaleX(X轴缩放) / scaleY(Y轴缩放)
ObjectAnimator sa = ObjectAnimator.ofFloat(imageView, "scaleX", 0,1,0,1); // 缩放比
sa.setDuration(2000);
sa.start();
}
/**
* 位移
*/
public void onclick4(View view){
// translationX / translationY
ObjectAnimator ta = ObjectAnimator.ofFloat(imageView, "translationX", 10,50,30,100); // 位移距离
ta.setDuration(2000);
ta.start();
}
/**
* 组合动画
*/
public void onclick5(View view){
// 属性动画集
AnimatorSet set = new AnimatorSet();
ObjectAnimator aa = ObjectAnimator.ofFloat(imageView, "alpha", 0,1,0,1,0,1);
ObjectAnimator ra = ObjectAnimator.ofFloat(imageView, "rotationX", 0,180,90,360);
ObjectAnimator sa = ObjectAnimator.ofFloat(imageView, "scaleX", 0,1,0,1);
ObjectAnimator ta = ObjectAnimator.ofFloat(imageView, "translationX", 10,50,30,100);
set.setDuration(2000);
set.setTarget(iv);
// 添加到动画集
// set.playSequentially(aa, ra, sa, ta); // 挨个执行
set.playTogether(aa, ra, sa, ta); // 一起执行
set.start();
}
/**
* 两个属性动画组合(api>=21)
*/
public void onclick6(View view){
Path path = new Path();
path.moveTo(0, 0); // 起始位置
path.lineTo(100, 100); // 经过位置
path.lineTo(50, 50);
// (参数:目标, 属性动画名1, 属性动画名2, path) (两个属性名可以为不同类型)
ObjectAnimator oa = ObjectAnimator.ofFloat(imageView, "rotationX", "rotationY", path);
oa.setDuration(2000);
oa.start();
}
xml实现
可将动画放入xml文件
- XML文件
<?xml version="1.0" encoding="utf-8"?>
<!--
android:valueFrom="float | int | color"
android:repeatMode="repeat | reverse"
android:valueType="intType | floatType(默认)"; 颜色不需要指定
-->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="restart"/>
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotationX"
android:valueFrom="0"
android:valueTo="180"
android:duration="2000"/>
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="scaleX"
android:valueFrom="0"
android:valueTo="1"
android:duration="2000"/>
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationX"
android:valueFrom="10"
android:valueTo="50"
android:duration="2000"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- android:ordering="together(默认:同时) | sequentially(顺序)" -->
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="restart"/>
<!-- ... -->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationX"
android:valueFrom="10"
android:valueTo="50"
android:duration="2000"/>
</set>
- 代码
/**
* 透明
*/
public void onclick1(View view){
ObjectAnimator oa = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.alpha);
oa.setTarget(imageView); // 设置目标
oa.start();
}
// 其他代码相同, 略
/**
* 组合动画
*/
public void onclick5(View view){
AnimatorSet oa = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.set);
oa.setTarget(imageView);
oa.start();
}
插值器
补间动画
代码设置
/**
* 透明
*/
public void onclick1(View view){
// 透明动画 [0, 1]
AlphaAnimation aa = new AlphaAnimation(1.0f, 0.0f);
aa.setDuration(2000); // 持续时间(毫秒)
aa.setRepeatCount(1); // 重复次数: [0,+] / NFINITE(一直重复)
aa.setRepeatMode(Animation.REVERSE); // 重复类型: REVERSE倒序回放 / RESTART从头播放
aa.setFillAfter(true); // 保持动画最后状态
aa.setInterpolator(new CycleInterpolator(7)); // 设置插值器
imageView.startAnimation(aa); // 执行动画
}
xml设置
<?xml version="1.0" encoding="utf-8"?>
<!-- android:interpolator="@anim/xxx" 设置插值器 -->
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="reverse"
android:fillAfter="true"
android:interpolator="@anim/cycle_7"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- 周期运动 -->
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:cycles="7" /> <!-- 循环7次 -->
属性动画
代码设置
/**
* 透明
*/
public void onclick1(View view){
// alpha 参数(目标, 属性动画名, 参数...)
ObjectAnimator aa = ObjectAnimator.ofFloat(imageView, "alpha", 0,1,0,1,0,1); // 透明度[0,1]
aa.setDuration(2000);
aa.setRepeatCount(1);
aa.setRepeatMode(ObjectAnimator.RESTART);
aa.setInterpolator(new CycleInterpolator(7)); // 设置插值器
aa.start();
}
XML设置
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="restart"
android:interpolator="@anim/cycle_7"/>
<!-- 插值器cycle_7代码见补间动画差值器 -->
ViewPropertyAnimator
ViewPropertyAnimator属性动画简化类, 链式调用, 为View设置动画, Android 3.1+
/**
* 透明
*/
public void onclick1(View view){
imageView.animate()
.alpha(0)
.alphaBy(1)
.setDuration(2000)
.setInterpolator(new CycleInterpolator(7))
.start();
}
/**
* 旋转
*/
public void onclick2(View view){
imageView.animate()
.rotationX(0)
.rotationXBy(180)
.setDuration(2000)
.start();
}
/**
* 缩放
*/
public void onclick3(View view){
imageView.animate()
.scaleX(0)
.scaleXBy(1)
.setDuration(2000)
.start();
}
/**
* 位移
*/
public void onclick4(View view){
imageView.animate()
.translationX(10)
.translationXBy(50)
.setDuration(2000)
.start();
}