Android 基本动画(帧动画/补间动画/属性动画)
本文由 Luzhuo 编写,转发请保留该信息.
原文: https://blog.csdn.net/Rozol/article/details/79730559
(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();
}