作者:xiaozhao | 来源:互联网 | 2024-11-01 15:31
本文介绍了Android动画的基本概念及其主要类型。Android动画主要包括三种形式:视图动画(也称为补间动画或Tween动画),主要通过改变视图的属性来实现动态效果;帧动画,通过顺序播放一系列预定义的图像来模拟动画效果;以及属性动画,通过对对象的属性进行平滑过渡来创建更加复杂的动画效果。每种类型的动画都有其独特的应用场景和实现方式,开发者可以根据具体需求选择合适的动画类型。
1.概述
1.1 定义
1.2 分类
Android动画有如下三种:
1.视图动画(View动画),也叫补间动画和Tween动画 | 主要通过指定View位置、角度、尺寸、透明度、变化时间和方式等属性的变化,进行图形变化,从而达到动画效果。其主要效果有如下: Translate(平移) Scale(缩放动画) Rotate(旋转) Alpha(透明度) 注意:View的属性并没有改变 |
2.逐帧动画(Frame Animation) | 通过指定每一帧的图片和播放时间,有序的进行播放而形成动画效果。 |
3.属性动画(Property Animation) | 通过不断的改变View的属性,不断的重绘而形成动画效果。相比于视图动画,常用的Java类包括: ValueAnimator ObjectAnimator AnimatorSet 注意:View的属性是真正的改变了 |
2.视图动画
2.1 概述
视图动画(View Animation)是通过对View中的内容进行一系列图形变换来实现动画效果,其中图形变换包括平移、缩放、旋转、改变透明度等。
视图动画可以通过XML文件来定义,也可以通过代码方式来实现。通常以XML文件形式的动画都会放置在自定义res/anim文件夹下。
2.2 包的定义
包为:android.view.animation
抽象类:其中有一个抽象类为Animation,其实现子类就是如2.3所示
2.3 分类
视图动画有5种补间动画,如下所示:
AlphaAnimation(透明度动画) |
RotateAnimation(旋转动画) |
ScaleAnimation(缩放动画) |
TranslateAnimation(平移动画) |
AnimationSet(集合动画) |
2.3.1 AlphaAnimation
1)概述
AlphaAnimation(透明度渐变动画)是通过改变View组件透明度来实现渐变效果。主要通过为动画指定开始时的透明度、结束时的透明度和动画持续的时间来创建动画。
2)常用属性
interpolator | 用于控制动画的变化速度,一般值为: @android:anim/linear_interpolator(匀速改变) @android:anim/accelerate_interpolator(开始慢,后面加速) |
repeatMode | 用于制定动画重复的方式,可选值如下: reverse(反向) restart(重新开始) |
repeatCount | 用于指定动画重复次数,属性值可以是正整数,也可以为infinite(无限循环) |
duration | 用于指定动画播放时长 |
fromAlpha | 用于指定动画开始时的透明度,0.0为完全透明,1.0为不透明 |
toAlpha | 用于指定动画结束时的透明度,0.0为完全透明,1.0为不透明 |
3)示例
在XML文件中定义透明度渐变动画,如下所示:定义了一个让View从完全不透明到透明,持续时间为1s的动画
aplha_animation.xml
2.3.2 RotateAnimation
1)概述
旋转动画就是通过为动画指定开始时的旋转角度、结束时的旋转角度和动画时长。
2)常用属性
fromDegress | 指定动画开始时的角度 |
toDegreaa | 指定动画结束时的角度 |
pivotX | 指定轴心的x坐标 |
piotY | 指定轴心的y坐标 |
3)示例
2.3.3 ScaleAnimation
1)概述
旋转动画就是通过为动画指定开始时的旋转角度、结束时的旋转角度和动画时长。
2)常用属性
fromXScale | 指定动画开始时X轴上的缩放系数,值为1.0表示不变化 |
fromYScale | 指定动画开始时Y轴上的缩放系数,值为1.0表示不变化 |
toXScale | 指定动画结束时X轴上的缩放系数,值为1.0表示不变化 |
toYScale | 指定动画结束时Y轴上的缩放系数,值为1.0表示不变化 |
3)示例
2.3.4 TranslateAnimation
1)概述
平移动画就是通过为动画指定开始位置、结束位置和动画时长。
2)常用属性
fromXDelta | 指定动画开始时View的X轴坐标 |
fromYDelta | 指定动画开始时View的Y轴坐标 |
toXDelta | 指定动画结束时View的X轴坐标 |
toYDelta | 指定动画结束时View的Y轴坐标 |
3)示例
2.3.5 AnimationSet
1)概述
AnimationSet(集合动画)就是包含两种及两种以上的动画的集合。
2)常用属性
3)实例
如下创建了一个包含旋转动画和平移动画的集合动画:
2.4 创建动画示例
XML文件方式 | 在XML文件中定义指定动画样式,然后在代码中: //创建动画实例,通过AnimationUtils加载资源 Animation animation = AnimationUtils.loadAnimation(Context context, int id); //为view设置并start动画 view.startAnimation(animation); |
动态代码方式 | 通过创建指定动画类型XXXAnimation实例对象,设置属性,然后startAnimation,如下所示: AlphaAniamtion alphaAnimtion = new AlphaAnimation(....); alphaAnimation.setXXX(...); view.startAnimation(alphaAnimation); |
2.4.1 用XML方式创建动画
xml配置文件如上2.3所示,布局如下:
Activity如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btnOne;private Button btnTwo;private Button btnThree;private Button btnFour;private Button btnFive;private ImageView imageView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btnOne= findViewById(R.id.btn_one);btnTwo = findViewById(R.id.btn_two);btnThree = findViewById(R.id.btn_three);btnFour = findViewById(R.id.btn_four);btnFive = findViewById(R.id.btn_five);imageView = findViewById(R.id.iv);btnOne.setOnClickListener(this);btnTwo.setOnClickListener(this);btnThree.setOnClickListener(this);btnFour.setOnClickListener(this);btnFive.setOnClickListener(this);}public void onClick(View view) {switch (view.getId()){case R.id.btn_one:Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_animation);imageView.startAnimation(alphaAnimation);break;case R.id.btn_two:Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate_animation);imageView.startAnimation(rotateAnimation);break;case R.id.btn_three:Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_animation);imageView.startAnimation(scaleAnimation);break;case R.id.btn_four:Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.translate_animation);imageView.startAnimation(translateAnimation);break;case R.id.btn_five:Animation setAnimation = AnimationUtils.loadAnimation(this, R.anim.set_animation);imageView.startAnimation(setAnimation);break;}}}
效果图如下:
2.4.2 用代码方式创建动画
在代码中定义动画,需要使用到Animation的实现子类,如AlphaAnimation, ScaleAnimation, TranslateAnimation, RotateAnimation,创建其对象,然后设置其属性,最后使得View控件startAnimation(Animation animation),传入实例对象进去即可。如下所示:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {private ImageView imageView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageView = findViewById(R.id.iv);//创建一个渐变透明度的动画,从透明到完全不透明AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);//设置动画时长alphaAnimation.setDuration(5000);//设置动画重复方式alphaAnimation.setRepeatMode(AlphaAnimation.REVERSE);//设置动画播放次数alphaAnimation.setRepeatCount(AlphaAnimation.INFINITE);//为View开启指定类型动画imageView.startAnimation(alphaAnimation);}
}
3.逐帧动画
3.1 原理
逐帧动画(Frame Animation)是按照事先准备好的静态图像顺序播放的,跟看胶片电影一样,利用人眼的“视觉暂留”原理,给用户造成动画的错觉。
使用逐帧动画需要使用AnimationDrawable类,它位于"android.graphics.drawable.AnimationDrawable"包下,是Drawable的间接子类。它主要用来创建一个逐帧动画,并且可以对帧进行拉伸,把它设置为View的背景即可使用AnimationDrawable.start()方法播放。
AnimationDrawable常用方法如下:
void start() | 开始播放逐帧动画 |
void stio() | 停止播放逐帧动画 |
void addFrame(Drawable frame,int duration) | 为AnimationDrawable添加一帧,并设置持续时间。 |
int getDuration(int i) | 得到指定index的帧的持续时间 |
Drawable getFrame(int index) | 得到指定index的帧Drawable |
int getNumberOfFrames() | 得到当前AnimationDrawable的所有帧数量 |
boolean isOneShot() | 得到当前帧动画是否只播放一次,true表示一次,false表示循环播放 |
boolean isRunning() | 得到当前帧动画是否正在播放 |
void setOneShot(boolean oneShot) | 设置当前帧动画是否只播放一次,true表示一次,false表示循环播放 |
3.2 创建方式
通过XML文件方式 | 在res/drawable目录下创建好帧动画的XML文件,并在节点的 字节点中, 指定图片帧出现的顺序和每帧持续的时间,然后在布局文件中引入,最后在代码中使用 view.getBackground()获取AnimationDrawable实例对象,通过此实例对象可以start()和stop()动画。 |
通过动态代码方式 | 创建AnimationDrawable实例对象,然后view.setBackground(实例对象),为实例对象设置addFrame( Drawable frame, int duration)和属性,最后start()即可。 |
3.3 案例
运行效果如下:点击start按钮后,图片按照指定时间一张张切换播放显示:
3.3.1 通过XML文件方式
1)定义xml文件:frame.xml
2)创建布局
3)处理代码
public class FrameActivity extends AppCompatActivity{private ImageView imageView;private Button btnStart;private AnimationDrawable animationDrawable;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_frame);imageView = findViewById(R.id.iv);btnStart = findViewById(R.id.btn_start);//获取AnimationDrawable对象animatiOnDrawable= (AnimationDrawable) imageView.getBackground();btnStart.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//判断动画是否在播放if (animationDrawable.isRunning()){//动画在播放,则暂停animationDrawable.stop();}else{//动画没有在播放,则进行播放animationDrawable.start();}}});}
}
3.3.2 通过动态代码方式
public class FrameActivity extends AppCompatActivity{private ImageView imageView;// private Button btnStart;private AnimationDrawable animationDrawable;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_frame);imageView = findViewById(R.id.image_view);//获取AnimationDrawable对象animatiOnDrawable= new AnimationDrawable();//为AnimationDrawable添加帧,并指定图片和时长animationDrawable.addFrame(getResources().getDrawable(R.drawable.timg), 1000);animationDrawable.addFrame(getResources().getDrawable(R.drawable.timg1), 1000);animationDrawable.addFrame(getResources().getDrawable(R.drawable.timg2), 1000);animationDrawable.addFrame(getResources().getDrawable(R.drawable.timg3), 1000);//循环播放animationDrawable.setOneShot(false);imageView.setBackground(animationDrawable);//播放Frame帧动画animationDrawable.start();}
}
4.属性动画
4.1 背景
属性动画是在Android3.0(API 11)后出现的一种新的动画模式。视图动画和逐帧动画存在一定的去缺点如下:
1.作用对象局限于继承自View的组件,无法对非View的对象进行动画操作。 |
2.没有改变View的属性,只是改变其视觉效果 |
3.动画效果单一 |
4.2 概述
1.属性动画作用对象为任意Java对象,不再仅限于View对象;2.可以自定义各种动画效果,不再仅限于4种基本变换:平移、旋转、缩放和透明度。
4.3 工作原理
从上面工作原理可以看出,属性动画有两个非常重要的类:ValueAnimator和ObjectAnimator。属性动画的使用基本都是依靠者两个类。
4.4 ValueAnimator
4.4.1 定义
ValueAnimator类属性动画机制中最核心的一个类,通过不断控制 值 的变化,再不断 手动 赋给对象的属性,从而实现动画效果
4.4.2 方法
ValueAnimator类有3个重要的方法如下所示:
ValueAnimator.ofInt(int... values) | 将初始值以整形数值的形式过度到结束值,即估值器是整形估值器(IntEvaluator) |
ValueAnimator.ofFloat(float... values) | 将初始值以浮点型数值的形式过渡到结束值 |
ValueAnimator.ofObject(TypeEvaluator evaluator, Object... values) | 将初始值以对象的形式过渡到结束值 |