Animation

动画

  • 帧动画

  • 补间动画

  • 属性动画

  • Interpolator

帧动画 FrameAnimation

其实就是一个Drawable ,将一系列的图片联合起来顺序的播放。形成动画效果。

帧动画本质就是一些图片的集合,要播放这个动画就必须将一系列的图片全部加载进内存中,所以帧动画的图片不易过大。

创建drawable文件

  • oneshot :是否只播放一次,

  • drawable :一帧的图片

  • duration :一帧播放的时间 毫秒单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

<?xml version="1.0" encoding="utf-8"?>

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">



<item android:drawable="@mipmap/a_01" android:duration="200"/>

<item android:drawable="@mipmap/a_02" android:duration="200"/>

<item android:drawable="@mipmap/a_03" android:duration="200"/>

<item android:drawable="@mipmap/a_04" android:duration="200"/>

<item android:drawable="@mipmap/a_5" android:duration="200"/>

<item android:drawable="@mipmap/a_6" android:duration="200"/>

</animation-list>

使用刚才的drawable文件做背景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

<ImageView

android:id="@+id/image"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:adjustViewBounds="true"

android:background="@drawable/drawable_frame"

android:clickable="true"

android:onClick="onClick"/>

播放动画

1
2
3
4

//FrameAnimation 帧动画

((AnimationDrawable)image.getBackground()).start();

image


补间动画 tweenAnimation

主要是对view的内容完成一系列的图形变换(缩放,透明,旋转,平移)来实现动画效果。
具体来说就是 预先定义一些指令 ,这些指令指定了图形变换的类型,触发时间,持续时间。指令可以预先定义在xml文件中也可以源代码的方式定义。程序沿着时间线执行这些指令就可以实现动画效果。

Android中提供了 Animation,Interpolator,Transformation 等类具体实现Tween动画,

Animation类及其子类是动画的核心模块,它实现了 各种动画效果如 平移 旋转 缩放 改变透明度等等。

Tween动画的每一帧都根据Interpolator对view的内容做一次图像变换,因此Animation的核心工作是做变换(transformation);

Animation是基类 ,它记录了动画的通用属性和方法。主要的属性包括动画持续时间、重复次数、Interpolator等。

常用属性

  • duration :动画时间 毫秒

  • infinite :无限次

  • fillAfter 是否停顿在最后一针

  • repeatMode 重复模式 值:restart 重新开始 reserve 反复

  • repeatCount :重复次数

  • startOffset :开始延迟时间

常用Animation子类:

  • AlphaAnimation 改变Alpha值

  • TranslationAnimation 平移动画

  • RotateAnimation 旋转动画

  • ScaleAnimation 缩放动画

  • AnimationSet 动画集合

实例

补间动画 既可以使用 xml文件预先定义 也可以使用代码动态创建;

使用xml文件定义必须在 res/anim/目录下创建 文件;

可以使用 AnimationUtils的静态方法 loadAnimation()将动画文件加载

AlphaAnimation 透明度改变动画

定义 AlphaAnimation 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

<?xml version="1.0" encoding="utf-8"?>

<alpha xmlns:android="http://schemas.android.com/apk/res/android"

android:fromAlpha="1"

android:toAlpha="0.1"

android:duration="2000"

android:repeatCount="5"

android:repeatMode="reverse">



</alpha>
加载 动画文件并播放
1
2
3
4
5
6

//AlphaAnimation xml定义

AlphaAnimation alphaAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_alpha);

view.startAnimation(alphaAnimation);
代码创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

//AlphaAnimation 代码创建

AlphaAnimation alphaAnimation1 = new AlphaAnimation(0.1f,0.8f);

alphaAnimation1.setDuration(2000);

alphaAnimation1.setStartOffset(100);

alphaAnimation1.setFillAfter(true);

alphaAnimation1.setRepeatCount(2);

alphaAnimation1.setRepeatMode(Animation.REVERSE);

view.startAnimation(alphaAnimation1);

TranslationAnimation 平移动画

  • fromXDelta X轴开始坐标

  • toXDelta X轴结束坐标

  • fromYDelta Y 轴开始坐标

  • toYDelta Y轴结束坐标

>

定义动画文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<?xml version="1.0" encoding="utf-8"?>

<translate xmlns:android="http://schemas.android.com/apk/res/android"

android:duration="2000"

android:fromXDelta="0"

android:toXDelta="300"

android:repeatMode="reverse"

android:repeatCount="3"

android:fillBefore="true"

android:fromYDelta="200"

android:toYDelta="100">

</translate>
加载动画并播放
1
2
3
4

TranslateAnimation translateAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_translation);

view.startAnimation(translateAnimation);
代码创建动画
1
2
3
4
5
6
7
8

TranslateAnimation translateAnimation1 = new TranslateAnimation(-10,100,0,0);

translateAnimation1.setInterpolator(new BounceInterpolator());

translateAnimation1.setDuration(2000);

view.startAnimation(translateAnimation1);

RotateAnimation 旋转动画

  • fromDegrees:起始角度

  • toDegrees:到达角度

  • pivotX:X轴中心点

  • pivotY:Y轴中心点

中心点取值模式:

  • 固定像素 50

  • 相对于自身 50%

  • 相对于父容器 50%p

定义动画文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

<?xml version="1.0" encoding="utf-8"?>

<rotate xmlns:android="http://schemas.android.com/apk/res/android"

android:pivotX="50%"

android:pivotY="50%"

android:toDegrees="90"

android:fromDegrees="0"

android:duration="2000"

android:fillAfter="true">

</rotate>
加载动画并播放
1
2
3
4

RotateAnimation rotate = (RotateAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_rotate);

view.startAnimation(rotate);
代码创建动画
1
2
3
4
5
6
7
8
9
10
11
12

//在右上角中心,0-180度

RotateAnimation rotate = new RotateAnimation(0, 180);

//(100,100)像素位中心

RotateAnimation rotate = new RotateAnimation(0, 180, 100, 100);

//相对于自身一半为中心

RotateAnimation rotate = new RotateAnimation(0, 180,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);

沿中心旋转 45°

1
2
3
4
5
6
7
8
9
10

RotateAnimation rotateAnimation = new RotateAnimation(0,45,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);

rotateAnimation.setInterpolator(new DecelerateInterpolator());

rotateAnimation.setDuration(2000);

rotateAnimation.setFillAfter(true);

view.startAnimation(rotateAnimation);

ScaleAnimation 缩放动画

  • fromXScale:X轴起始缩放值

  • fromYScale:Y轴起始缩放值

  • toXScale:X轴到达缩放值

  • toYScale:Y轴到达缩放值

  • 缩放值可以是缩放倍数,也可以是缩放到具体尺寸

定义动画文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<?xml version="1.0" encoding="utf-8"?>

<scale xmlns:android="http://schemas.android.com/apk/res/android"

android:fromXScale="0"

android:toXScale="2"

android:fromYScale="0"

android:toYScale="3"

android:duration="2000"

android:pivotY="50%"

android:pivotX="50%">



</scale>
加载动画并播放
1
2
3
4

ScaleAnimation scale = (ScaleAnimation) AnimationUtils.loadAnimation(this,R.anim.anim_scale);

view.startAnimation(scale);
代码创建动画
1
2
3
4
5
6

ScaleAnimation scale = new ScaleAnimation(0, 2, 0, 2);

ScaleAnimation scale = new ScaleAnimation(0, 2, 0, 2, 100, 100);

ScaleAnimation scale = new ScaleAnimation(0, 2, 0, 2,Animation.RELATIVE_TO_PARENT, 0.5f,Animation.RELATIVE_TO_PARENT, 0.5f);

AnimationSet 动画集合

定义动画文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"

android:duration="2000">



<rotate android:pivotX="0"

android:pivotY="0"

android:fromDegrees="-180"

android:toDegrees="0"/>



<scale android:pivotX="50%"

android:pivotY="50%"

android:fromXScale="0"

android:toXScale="1"

android:fromYScale="0"

android:toYScale="1"/>



</set>
加载动画并播放
1
2
3
4

Animation animation = AnimationUtils.loadAnimation(this,R.anim.anim_set);

view.startAnimation(animation);
代码创建动画
1
2
3
4
5
6
7
8
9
10
11
12
13
14

//子动画是否共用差值器

AnimationSet set = new AnimationSet(true);

set.addAnimation(new RotateAnimation(-180,0));

set.addAnimation(new ScaleAnimation(0,1,0,1,Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF,0.5f));

set.setDuration(2000);

set.setFillAfter(true);

view.startAnimation(set);

Interpolator

Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。

常用的差值器

  • LinearIntepolator 匀速效果

  • DecelerateInterpolator 减速效果

  • Accelerateinterpolator 加速效果

  • CycleInterpolator 循环效果

  • BouncedInterpolator 弹跳效果


Property Animation 属性动画

属性动画的用处有很多很多,我就列几个常用的方式把;具体参考官网文档:https://developer.android.com/guide/topics/graphics/prop-animation.html

补间动画并不能改变view真实的位置,只是形式上的位置改变。而属性动画会将view的真实位置改变。

属性动画定义必须在 res/animator目录下

ValueAnimation

valueType 常用三种取值:

  • intType整数值、

  • floatType浮点值、

  • colorType颜色值、

定义动画文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

<?xml version="1.0" encoding="utf-8"?>

<animator xmlns:android="http://schemas.android.com/apk/res/android"

android:valueFrom="2"

android:valueTo="200"

android:duration="2000"

android:valueType="intType"

android:interpolator="@android:interpolator/linear">



</animator>

加载动画 并添加 动画监听

属性动画 就是在 监听中去改变控件的属性的值 ,让控件 位置和形态的属性都发生真正的变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.animator_value);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

//intType

int value= (int) animation.getAnimatedValue();

image.setTranslationY(value);

// image.setTranslationX(value);



//floatType

// float alpha = (float) animation.getAnimatedValue();

// image.setAlpha(alpha);



}

});

代码创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

// ValueAnimator valueAnimator = ValueAnimator.ofFloat(1f,0.5f,0f);

PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofFloat("alpha",1f,0.5f);

PropertyValuesHolder widthHolder = PropertyValuesHolder.ofInt("width",1,200);

PropertyValuesHolder rotateHolder = PropertyValuesHolder.ofFloat("rotate",0,180);

ValueAnimator valueAnimator = ValueAnimator.ofPropertyValuesHolder(alphaHolder,widthHolder,rotateHolder);

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

// float value= (float) animation.getAnimatedValue();

// image.setAlpha(value);



float alpha= (float) animation.getAnimatedValue("alpha");

int width = (int) animation.getAnimatedValue("width");

float rotate = (float) animation.getAnimatedValue("rotate");

Log.e("MainActivity","alpha:"+alpha);

Log.e("MainActivity","width:"+width);



image.setAlpha(alpha);

image.setMaxWidth(width);

image.setMinimumWidth(width);

image.setRotation(rotate);

}

});

valueAnimator.setDuration(2000);

valueAnimator.start();

ObjectAnimator

大部分属性都和ValueAnimator相同,只多了对要控制改变的控件的属性的声明

propertyName:要控制的控件的属性名;

动画会直接修改制定属性名的属性

需要注意:设置了getter/setter方法的属性才能生效

定义动画文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

<?xml version="1.0" encoding="utf-8"?>

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"

android:propertyName="rotation"

android:valueFrom="0"

android:valueTo="45"

android:duration="2000"

android:valueType="floatType">

<!--

rotation

rotationY

rotationX



-->



</objectAnimator>

加载动画并设置播放动画的对象

1
2
3
4
5
6

ObjectAnimator object = (ObjectAnimator) AnimatorInflater.loadAnimator(this,R.animator.animator_object);

object.setTarget(image);

object.start();

代码创建动画

凡是 有get/set方法的属性都可以设置值

1
2
3
4
5
6
7
8
9
10

// ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(image,"alpha",1f,0.2f);

ObjectAnimator objectAnimator = ObjectAnimator.ofInt(view,"backgroundColor", Color.RED,Color.YELLOW,Color.BLUE,Color.GREEN);

objectAnimator.setDuration(2000);

objectAnimator.setInterpolator(new BounceInterpolator());

objectAnimator.start();

完整代码github地址:https://github.com/sky-mxc/AndroidDemo/tree/master/animation

坚持原创技术分享,您的支持将鼓励我继续创作!