总结一下android动画常用方法。
分类
- 帧动画
- view动画(视图动画)
- 属性动画
帧动画
即逐帧播放动画
用法:在res/drawable文件新建资源文件anim_grass,如下
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item
android:drawable="@drawable/ic_fav_anim1"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim2"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim3"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim4"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim5"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim6"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim7"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim8"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim9"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim10"
android:duration="100" />
<item
android:drawable="@drawable/ic_fav_anim11"
android:duration="100" />
</animation-list>
其中oneshot
代表着是否只展示一遍,设置为false会不停的循环播放动画
在Java代码中使用:
AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(
R.drawable.anim_grass);
mAnimImageView.setBackground(animationDrawable);
animationDrawable.start();
// 或
// mAnimImageView.setImageResource(R.drawable.anim_grass);
// animationDrawable = (AnimationDrawable) mAnimImageView.getDrawable();
// animationDrawable.start();
View(视图)动画
视图动画,也叫Tween(补间)动画。对view进行位移(translation)、伸缩(scale)、旋转(rotate )、透明度(alpha)等一系列操作的动画。只是改变了View的视觉效果,而不会真正去改变View的属性。
1、在XML中定义动画
文件放在res/anim/路径下
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:duration="300"
android:fromXDelta="-30%p"
android:toXDelta="0%p" />
</set>
translate动画
fromXDelta: 为动画起始时 X坐标上的位置
toXDelta: 为动画结束时 X坐标上的位置
fromYDelta: 为动画起始时 Y坐标上的位置
toYDelta: 为动画结束时 Y坐标上的位置
android:toXDelta="100%",表示自身的100%,也就是从View自己的位置开始。
android:toXDelta="80%p",表示父层View的80%,是以它父层View为参照的。
使用:
mView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.translate_in));
scale 动画
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0.0"
android:toXScale="1.4"
android:fromYScale="0.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:duration="700"
android:fillAfter="true"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="5"
android:repeatMode ="reverse"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
</scale>
属性含义:
android:fillAfter="true" 动画结束后,保持结束时的状态
android:fillBefore="true" 动画结束后,恢复为初始状态
android:fillEnabled="true" 效果同上
android:repeatCount="5" 重复次数,取值为-1时无限重复,默认动画执行一次
android:repeatMode ="reverse" 重复模式,有reverse和restart两个值,前者为倒序回放,后者为重新开始
android:interpolator 插值器
使用:
private ScaleAnimation mScaleAnimation;
mScaleAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(this,R.anim.scale_in);
mView.startAnimation(mScaleAnimation);
rotation 动画
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_launcher"
android:duration="1500"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:toDegrees="359"
android:visible="true" />
属性:
android:drawable 需要进行旋转动画的图片
android:fromDegrees 旋转的起始点(旋转开始的角度)
android:toDegrees 旋转的结束点(旋转最终角度)
andoird:pivotX 旋转点的X值(距离左侧的偏移量)
android:pivotY 旋转点的Y值(距离顶部的偏移量)
android: visible 图片初始的显示状态
android:repeatCount 重复的次数,默认为0,必须是int,可以为-1表示不停止
android:interpolator="@android:anim/linear_interpolator" 设置转动速率,这里设置的是匀速转动
alpha 动画
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="700"
android:fillAfter="true"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="5"
android:repeatMode ="reverse"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
</alpha>
属性:
android:fromAlpha="1.0" 起始透明度,取值范围0.0--1.0 ,从完全透明到完全不透明
android:toAlpha="0.1" 结束透明度,取值范围同上
android:duration="700" 动画持续时间,毫秒为单位
android:fillAfter="true" 动画结束后,保持结束时的状态
android:fillBefore="true" 动画结束后,恢复为初始状态
android:fillEnabled="true" 效果同上
android:repeatCount="5" 重复次数,取值为-1时无限重复,默认动画执行一次
android:repeatMode ="reverse" 重复模式,有reverse和restart两个值,前者为倒序回放,后者为重新开始
2、在Java代码中定义动画
//translate
Animation translateAnimation = new TranslateAnimation(0, 100, 0, 0);
translateAnimation.setDuration(500);
translateAnimation.setInterpolator(this, android.R.anim.cycle_interpolator);//设置动画插入器
translateAnimation.setFillAfter(true);//设置动画结束后保持当前的位置(即不返回到动画开始前的位置)
mView.startAnimation(translateAnimation);
//scale
Animation scaleAnimation = new ScaleAnimation(0.0f, 1.5f, 0.0f, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(500);//设置动画持续时间为500毫秒
scaleAnimation.setFillAfter(true);//如果fillAfter的值为true,则动画执行后,控件将停留在执行结束的状态
scaleAnimation.setFillBefore(false);//如果fillBefore的值为true,则动画执行后,控件将回到动画执行之前的状态
scaleAnimation.setRepeatCount(3);//设置动画循环次数
scaleAnimation.setRepeatMode(Animation.REVERSE);
scaleAnimation.setStartOffset(0);
scaleAnimation.setInterpolator(this, android.R.anim.decelerate_interpolator);//设置动画插入器
mView.startAnimation(scaleAnimation);
//rotation
Animation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(500);
rotateAnimation.setFillAfter(true);
rotateAnimation.setInterpolator(this, android.R.anim.accelerate_decelerate_interpolator);//设置动画插入器
mView.startAnimation(rotateAnimation);
//alpha
Animation alphaAnimation = new AlphaAnimation(0f,1f);
alphaAnimation.setDuration(1000);
alphaAnimation.setRepeatCount(2);
mView.startAnimation(alphaAnimation);
代码封装
public class AnimatorUtils {
public static final String ROTATION = "rotation";
public static final String SCALE_X = "scaleX";
public static final String SCALE_Y = "scaleY";
public static final String TRANSLATION_X = "translationX";
public static final String TRANSLATION_Y = "translationY";
public static final String ALPHA = "alpha";
public static PropertyValuesHolder rotation(float... values) {
return PropertyValuesHolder.ofFloat(ROTATION, values);
}
public static PropertyValuesHolder translationX(float... values) {
return PropertyValuesHolder.ofFloat(TRANSLATION_X, values);
}
public static PropertyValuesHolder translationY(float... values) {
return PropertyValuesHolder.ofFloat(TRANSLATION_Y, values);
}
public static PropertyValuesHolder scaleX(float... values) {
return PropertyValuesHolder.ofFloat(SCALE_X, values);
}
public static PropertyValuesHolder scaleY(float... values) {
return PropertyValuesHolder.ofFloat(SCALE_Y, values);
}
public static PropertyValuesHolder alpha(float... values) {
return PropertyValuesHolder.ofFloat(ALPHA, values);
}
}
属性动画
属性动画在Android3.0(SDK11)出现的一种新的动画类型。会对目标的属性进行修改。
ValueAnimator
用法:
ValueAnimator mValueAnimator;
Button mValueBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anima);
mValueBtn = findViewById(R.id.btn_value);
mValueAnimator = ValueAnimator.ofInt(0,1000).setDuration(2000);
//监听动画执行
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currValue = (int) animation.getAnimatedValue();
mValueBtn.layout(mValueBtn.getLeft(), currValue, mValueBtn.getRight(), currValue + mValueBtn.getHeight());
}
});
mValueAnimator.setInterpolator(new BounceInterpolator());
mValueAnimator.start();
}
ObjectAnimator
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mValueBtn, "translationY", 0,1000).setDuration(1000);
objectAnimator.setInterpolator(new BounceInterpolator());
objectAnimator.start();
AnimatorSet
可以使用AnimatorSet来执行一系列动画
mAnimatorSet = new AnimatorSet();
ObjectAnimator snakeAnima = ObjectAnimator.ofFloat(mView, "translationX", 0, 25, -25, 25, -25, 15, -15, 6, -6, 0).setDuration(1000);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(mView,"scaleX",0f,1f).setDuration(500);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(mView,"scaleY",0f,1f).setDuration(500);
ObjectAnimator tranX = ObjectAnimator.ofFloat(mView,"translationX",-tx,0);
ObjectAnimator tranY = ObjectAnimator.ofFloat(mView,"translationY",ty,0);
//执行scaleX的同时执行scaleY,tranX,tranY
mAnimatorSet.play(scaleX)
.with(scaleY)
.with(tranX)
.with(tranY);
//执行snakeAnima完成后执行scaleX动画
mAnimatorSet.play(snakeAnima).after(scaleX);
//动画执行监听
mAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
在XML文件中定义
文件放在res/animator/路径下
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime">
<objectAnimator
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="0.5"
android:valueTo="1.0"/>
<objectAnimator
android:propertyName="scaleX"
android:valueType="floatType"
android:valueFrom="1.0"
android:valueTo="1.8"/>
<objectAnimator
android:propertyName="scaleY"
android:valueType="floatType"
android:valueFrom="1.0"
android:valueTo="1.8"/>
</set>
一些属性:
- propertyName 属性名称
- duration 动画时长
- valueFrom 属性起始值
- valueTo 属性结束值
- startOffset 动画延迟时间(ms)
- repeatCount 动画重复次数
- repeatMode 重复模式(重头开始重复播放和倒着重复播放)
- valueType 动画值类型
使用XML中的属性动画
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.scale_with_alpha);
animator.setTarget(mValueBtn);
animator.start();