一、引言
1、Android 中动画有多种, 常用的有两种, 即view动画和属性动画,这两者在视觉效果上并没太大不同, 实现方式也是大同小异, 但有一个显著区别:
例如一个平移动画, 在视觉上都感觉控件已经离开了原来的位置, 但view动画并不改变控件对触摸和点击的响应位置, 控件的响应范围还在控件最初始的位置,点击视觉上的位置并不生效;
但属性动画的响应范围和位置却会随着控件动画的变化而变化。
2、另一个区别一般用不到, 也是在测试时无意发现, 对同一个控件执行不同的动画, view动画会默认清除上一个动画的效果, 但属性动画却会保留上一个动画的效果, 即属性动画连续执行多个动画而不手动清除效果, 就会变成混合动画。
3、Android 中动画设置比较简单, 但不同动画混合的效果千变万化, 项目的工具类 BasisAnimUtils 只是提供给一个参考, 具体应用时最好重新编写。
4、项目地址: https://github.com/GinGod/BasisDependency , 具体参考类:BasisAnimUtils 和 AnimationActivity
二、view动画
1、几个通用方法解释
a. setDuration(long durationMillis) 设置单次动画播放时长, 单位是 ms(毫秒)
b. setRepeatCount(int repeatCount) 设置动画重复次数, 常用值: Animation.INFINITE (无限次)
c. setRepeatMode(int repeatMode) 设置重复模式,常用值: Animation.REVERSE (反转开始), Animation.RESTART(重新开始)
d. setFillAfter(boolean fillAfter) 设置动画结束后控件停留的位置,常用值: false (默认)回到原始位置, true 停留在动画停止的最后一帧上
e. setInterpolator(Interpolator i) (不常用)动画执行速率, 常用值:new LinearInterpolator() 匀速(在连续旋转中用到)
2、透明(alpha)动画
/**
* 透明度渐变的动画
*/
public static void alpha(View view) {
AlphaAnimation aa = new AlphaAnimation(1.0f, 0.2f);
// 动画播放的时间长度
aa.setDuration(2000);
// 设置重复播放的次数
aa.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
aa.setRepeatMode(Animation.REVERSE);
//动画结束后还原到初始状态
aa.setFillAfter(true);
// 让iv播放aa动画
view.startAnimation(aa);
}
3、平移(translate)动画
Animation.RELATIVE_TO_SELF 相对于自己
Animation.RELATIVE_TO_PARENT 相对于父窗口
Tip: 相对于父窗口是相对于view的直接父控件, 若控件被某一ViewGroup包裹, 测试发现动画只在父窗口范围内显示, 超出父窗口的位置不显示, 后面动画类似
/**
* 平移动画
*/
public static void trans(View view) {
//相对于父窗口是相对于view的父控件, 测试发现动画只在父窗口范围内显示, 超出父窗口的位置不显示
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.5f);
// 动画播放的时间长度
ta.setDuration(2000);
// 设置重复播放的次数
ta.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
ta.setRepeatMode(Animation.REVERSE);
//动画结束后还原到初始状态
ta.setFillAfter(false);
// 让iv播放aa动画
view.startAnimation(ta);
}
4、缩放(scale)动画
/**
* 缩放动画
*/
public static void scale(View view) {
ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
// 动画播放的时间长度
sa.setDuration(2000);
// 设置重复播放的次数
sa.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
sa.setRepeatMode(Animation.REVERSE);
//动画结束后还原到初始状态
sa.setFillAfter(false);
// 让iv播放aa动画
view.startAnimation(sa);
}
5、旋转(rotate)动画
/**
* 旋转动画
*/
public static void rotate(View view) {
RotateAnimation ra = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
// 动画播放的时间长度
ra.setDuration(2000);
// 设置重复播放的次数
ra.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
ra.setRepeatMode(Animation.REVERSE);
//动画结束后还原到初始状态
ra.setFillAfter(false);
// 让iv播放aa动画
view.startAnimation(ra);
}
6、集合(set)动画
集合动画可以将不同的动画在同一时间播放,以实现复杂的动画效果
/**
* 动画合集 集合
*/
public static void set(View view) {
AnimationSet set = new AnimationSet(false);
AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);
// 动画播放的时间长度
aa.setDuration(2000);
// 设置重复播放的次数
aa.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
aa.setRepeatMode(Animation.REVERSE);
RotateAnimation ra = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
// 动画播放的时间长度
ra.setDuration(2000);
// 设置重复播放的次数
ra.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
ra.setRepeatMode(Animation.REVERSE);
ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
// 动画播放的时间长度
sa.setDuration(2000);
// 设置重复播放的次数
sa.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
sa.setRepeatMode(Animation.REVERSE);
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f);
// 动画播放的时间长度
ta.setDuration(2000);
// 设置重复播放的次数
ta.setRepeatCount(Animation.INFINITE);
// 设置重复播放的模式
ta.setRepeatMode(Animation.REVERSE);
set.addAnimation(aa);
set.addAnimation(ta);
set.addAnimation(sa);
set.addAnimation(ra);
view.startAnimation(set);
}
三、使用 .xml 资源文件实现动画
1、透明动画
2、平移动画
3、缩放动画
4、旋转动画
5、集合动画
6、代码实现
引用资源文件实现动画就两行代码, 工具类对其进行了简单封装
/**
* 透明度渐变的动画
*/
public static void alpha(Context context, View view) {
anim(context, view, R.anim.anim_view_alpha);
}
/**
* 平移动画
*/
public static void trans(Context context, View view) {
anim(context, view, R.anim.anim_view_trans);
}
/**
* 缩放动画
*/
public static void scale(Context context, View view) {
anim(context, view, R.anim.anim_view_scale);
}
/**
* 旋转动画
*/
public static void rotate(Context context, View view) {
anim(context, view, R.anim.anim_view_rotate);
}
/**
* 连续旋转动画
*/
public static void rotateContinue(Context context, View view) {
anim(context, view, R.anim.anim_view_rotate_continue);
}
/**
* 动画合集 集合
*/
public static void set(Context context, View view) {
anim(context, view, R.anim.anim_view_set);
}
/**
* 资源动画
*/
public static void anim(Context context, View view, int animId) {
Animation aa = AnimationUtils.loadAnimation(context, animId);
view.startAnimation(aa);
}
四、属性动画
属性动画的四个基本动画都是使用的同一个类ObjectAnimator, 只是根据传入参数的不同来执行不同的动画, 参数有
alpha 透明动画
translationX X方向平移动画
translationY Y方向平移动画
scaleX X方向缩放动画
scaleY Y方向缩放动画
rotationX X方向旋转动画
rotationY Y方向旋转动画
具体代码封装如下:
/**
* 透明度渐变的动画
*
* @param view
*/
public static void alphaOfObject(View view) {
animOfObject(view, "alpha", new float[]{
0.2f, 0.4f, 0.6f, 0.8f, 1.0f});
}
/**
* 平移动画
*
* @param view
*/
public static void transOfObject(View view) {
animOfObject(view, "translationX",
new float[]{10f, 20f, 30f, 40f, 60f, 80f});
}
/**
* 缩放动画
*/
public static void scaleOfObject(View view) {
// iv.setScaleX(scaleX)
animOfObject(view, "scaleX", new float[]{
1f, 2f, 3f, 4f, 5f, 6f});
}
/**
* 旋转动画
*/
public static void rotateOfObject(View view) {
animOfObject(view, "rotationY",
new float[]{90f, 180f, 270f, 360f});
}
/**
* 属性动画(执行时不会清除原有动画)
*/
public static void animOfObject(View target, String propertyName, float... values) {
ObjectAnimator oa = ObjectAnimator.ofFloat(target, propertyName, values);
oa.setDuration(2000);
oa.setRepeatCount(ObjectAnimator.INFINITE);
oa.setRepeatMode(ObjectAnimator.REVERSE);
oa.start();
}
/**
* 属性动画合集 集合
*/
public static void setOfObject(View view) {
AnimatorSet set = new AnimatorSet();
ObjectAnimator oa = ObjectAnimator.ofFloat(view, "translationX",
new float[]{10f, 20f, 30f, 40f, 60f, 80f});
oa.setDuration(3000);
ObjectAnimator oa2 = ObjectAnimator.ofFloat(view, "translationY",
new float[]{-10f, -20f, -30f, -40f, -60f, -80f});
oa2.setDuration(3000);
set.playTogether(oa, oa2);
set.start();
}
/**
* 清除动画
*/
public static void clearAnimation(View... views) {
for (int i = 0; i < views.length; i++) {
views[0].clearAnimation();
}
}
五、项目地址
项目地址: https://github.com/GinGod/BasisDependency , 具体参考类:BasisAnimUtils 和 AnimationActivity