Android中的动画可以分为几类:
1.View Animation:视图动画,也叫做Tween (补间)动画,可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度)。
2.Drawable Animation:也叫做Frame动画,帧动画,元咯是将一张张单独的图片连贯的进行播放,从而在视觉上产生一种动画效果;有点类似幻灯片的播放以及gif动画。
3.Property Animation:属性动画,可以实现视图动画做不到的事,原理就是修改控件的属性值实现的动画。
下面分布介绍以上三种动画:
1.视图动画:
分为四种形式,分别是 alpha(淡入淡出),translate(位移),scale(缩放大小),rotate(旋转)。 视图动画的实现,一般会采用xml 文件的形式;代码会更容易书写和阅读,同时也更容易复用。
1.1Alpha:
相关属性:
android:fromAlpha 动画开始的透明度,从0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明;
android:toAlpha 动画结束时的透明度,也是从0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明;
anim_alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0"
android:toAlpha="1" />
case R.id.mBtn_alpha:
mAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_alpha);
mAnimation.setDuration(3000);
mImg.startAnimation(mAnimation);
效果:
1.2 Translate
相关属性:
android:interpolator: 加速器,非常有用的属性,可以简单理解为动画的速度,可以是越来越快,也可以是越来越慢,或者是先快后忙,或者是均匀的速度等等。
@android:anim/accelerate_interpolator: 越来越快
@android:anim/decelerate_interpolator:越来越慢
@android:anim/accelerate_decelerate_interpolator:先快后慢
@android:anim/anticipate_interpolator: 先后退一小步然后向前加速
@android:anim/overshoot_interpolator:快速到达终点超出一小步然后回到终点
@android:anim/anticipate_overshoot_interpolator:到达终点超出一小步然后回到终点
@android:anim/bounce_interpolator:到达终点产生弹球效果,弹几下回到终点
@android:anim/linear_interpolator:均匀速度。
fromXDelta 属性为动画起始时 X坐标上的位置
toXDelta 属性为动画结束时 X坐标上的位置
fromYDelta 属性为动画起始时 Y坐标上的位置
toYDelta 属性为动画结束时 Y坐标上的位置
注意:
没有指定,默认是以自己为相对参照物 。在这些属性里面还可以加上%和p。
anim_translate.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/linear_interpolator"
android:toXDelta="200"
android:toYDelta="0" />
case R.id.mBtn_translate:
mAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_translate);
mAnimation.setDuration(1500);
mAnimation.setFillAfter(true);
mImg.startAnimation(mAnimation);
效果:
1.3 Scale
相关属性:
pivotX:动画开始时,View所处的X轴坐标
pivotY:动画开始时,View所处的Y轴坐标
需要明确的是,这里以进行动画控件的左上角为原点坐标
fromXScale:属性为动画起始时 X坐标上的伸缩尺寸
fromYScale:属性为动画起始时 Y坐标上的伸缩尺寸
toXScale:属性为动画结束时 X坐标上的伸缩尺寸
toYScale:属性为动画结束时 Y坐标上的伸缩尺寸
anim_scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0"/>
case R.id.mBtn_scale:
mAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_scale);
mImg.startAnimation(mAnimation);
break;
效果:
1.4 rotate
相关属性:
android:fromDegrees 起始的角度度数
android:toDegrees 结束的角度度数,负数表示逆时针,正数表示顺时针。
anim_rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="90" />
case R.id.mBtn_rotate:
mAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_rotate);
mAnimation.setDuration(1500);
mAnimation.setFillAfter(true);
mImg.startAnimation(mAnimation);
break;
效果:
看一个效果:
设置View的点击事件,当View发生位移后,点击事件仍然再原来的位置,而不是发生位移后的位置。视图动画只是将这个View绘制到位移后的位置,改变了视觉效果而已,视图动画只是改变了View的视觉效果,而不会真正去改变View的属性。
2. 帧动画
在Drawable文件夹中放入多张图片,并在Drawable文件夹创建anim_fram.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/jd1" android:duration="50" />
<item android:drawable="@drawable/jd2" android:duration="50" />
<item android:drawable="@drawable/jd3" android:duration="50" />
<item android:drawable="@drawable/jd4" android:duration="50" />
</animation-list>
package cn.zzw.animationdemo;
import android.graphics.drawable.AnimationDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.AppCompatImageView;
public class FrameAnimationActivity extends AppCompatActivity {
AnimationDrawable mAnimationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame_animation);
setTitle("帧动画");
AppCompatImageView mImg = findViewById(R.id.mImg);
mImg.setBackgroundResource(R.drawable.anim_frame);
mAnimationDrawable = (AnimationDrawable) mImg.getBackground();
mAnimationDrawable.start();
}
}
效果:
3. 属性动画
属性动画主要有两个类:ValueAnimator, ObjectAnimator。
它们的关系如下图:
3.1 ObjectAnimator:
3.1.1 实现视图动画
//渐变动画
private void doAlphaByCode(View view) {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.0f,1.0f);
// 设置动画时常
animator.setDuration(3000);
// 设置重复次数
animator.start();
}
// 平移 X 轴
private void doTranslateXByCode(View view){
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationX",0f,200f,0f)
.setDuration(3000);
animator.start();
}
// 平移 Y 轴
private void doTranslateYByCode(View view){
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationY",0f,200f,0f);
// 设置动画时常
animator.setDuration(3000);
animator.start();
}
// 缩放 X 轴
private void doScaleXByCode(View view){
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"scaleX",1f,3f,1f);
// 设置动画时常
animator.setDuration(3000);
animator.start();
}
// 缩放 Y 轴
private void doScaleByCode(View view){
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"scaleX",1f,3f,1f);
// 设置动画时常
animator.setDuration(3000);
animator.start();
}
// 旋转动画
private void doRotateByCode(View view){
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"rotation",0f,360f,0f);
// 设置动画时常
animator.setDuration(3000);
animator.start();
}
列举一个效果:
3.2 ValueAnimator
ValueAnimator本身不作用与任何对象,也就是说直接使用时没有任何动画效果的。它可以对一个值做动画。
例子:
private void startValueAnimator()
{
ValueAnimator valueAnimator=ValueAnimator.ofInt(0,100);
valueAnimator.setDuration(3000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
if(value==100)
{
mBtn_value.setText("Button");
}else{
mBtn_value.setText(""+value);
}
}
});
valueAnimator.start();
}
效果: