0. 前言
Android动画是面试的时候经常被问到的话题。我们都知道Android动画分为三类:View动画、帧动画和属性动画。
先对这三种动画做一个概述:
View动画是一种渐进式动画,通过图像的平移、缩放、旋转和透明度等各种渐进式变换完成动画效果。
帧动画是通过不停的切换图片实现动画效果。
属性动画是不停的改变对象的属性来实现动画效果。本文原创,转载请注明出处:
http://blog.csdn.net/seu_calvin/article/details/52724655
1. View动画
1.1 系统提供的四种View动画(补间动画)
View动画可以在res/anim/name.xml文件里进行配置,四种View动画的渐变式变换分别对应<translate>、<scale>、<rotate>、<alpha>四个标签,动画集合可以使用<set>标签。xml的各个动画属性比较简单,这里就不再贴实例代码了。只需要注意如何应用配置好的xml文件来启动动画即可:
view.startAnimation(AnimationUtils.loadAnimation(this,R.anim.myanimation));
这些当然也可以在Java代码里进行配置,也比较简单,这里写了一个示例代码:
splash = (RelativeLayout)findViewById(R.id.splash); //旋转动画 RotateAnimation rotateAnimation = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); rotateAnimation.setDuration(2000); rotateAnimation.setFillAfter(true); //缩放动画 ScaleAnimation scaleAnimation = new ScaleAnimation(0,1,0,1, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); scaleAnimation.setDuration(2000); scaleAnimation.setFillAfter(true); //渐变动画 AlphaAnimation alphaAnimation = new AlphaAnimation(0.2f,1.0f); alphaAnimation.setDuration(2000); alphaAnimation.setFillAfter(true); //平移动画 TranslateAnimation translateAnimation = newTranslateAnimation (0,0,100,100); translateAnimation.setDuration(2000); translateAnimation.setFillAfter(true); //动画集合 AnimationSet animationSet = new AnimationSet(true); animationSet.addAnimation(rotateAnimation); animationSet.addAnimation(scaleAnimation); animationSet.addAnimation(alphaAnimation); animationSet.addAnimation(translateAnimation); //启动动画 plash.startAnimation(animationSet);
1.2 自定义View动画
自定义动画实际应用中比较少见,因此这里只做简单介绍。
完成自定义动画需要继承Animation类,并重写其initialize()以及applyTransformation()。
前者用于一些初始化的操作,后者用于进行矩阵变换。
1.3 为ViewGroup的所有子元素设置动画
上面1.1,1.2都是给View设置动画效果,Android同样提供了为ViewGroup设置
android:layoutAnimation=”@anim/layout_anim”来达到给ViewGroup中所有子元素设置动画的目的。下面给出相关代码:
//res/anim/anim/layout_anim.xml <layoutAnimation xmlns:android=” http://schemas.android.com/apk/res/android” android:delay=”0.1” //动画延迟时间为0.1*T,本例为100ms android:animationOrder=”normal” //子元素的播放动画顺序为顺序,也有reverse以及random android: animation=” @anim/layout_anim_item”/> //res/anim/anim/layout_anim_item.xml <?xml version=”1.0” encoding=”utf-8”?> <set xmlns:android=”http://schemas.android.com/apk/res/android” animation:duration=”200” //每个子元素的动画周期T animation:interpolator=”@android:anim/accelerate_ interpolator” //指定插值器 animation:shareInterpolator=”true”> //表示所有子元素共享该插值器 <alpha android:fromAlpha=”0.2” android: toAlpha =”1.0”/> <translate android:fromXDelta=”100” android: toXDelta =”0”/> </set>
1.4 为Activity切换设置动画
估计大家也都用过,在startActivity()之后使用,使Activity切换时达到一个平移的动画效果:
overridePendingTransition(R.anim.tran_in,R.anim.tran_out);
//res/anim/tran_in <?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" //表示从屏幕100%的位置开始,因此tran_out当然是toXDelta="-100%p",其他不变 android:fromXDelta="100%p" android:fromYDelta="0" android:toXDelta="0" android:toYDelta="0" > </translate>
2. 帧动画
上面也提到了,帧动画就是不停的切换图片实现动画效果。很明显容易OOM,所以使用帧动画要注意图片大小。
帧动画的使用也很简单,使用示例如下:
//res/drawable/myanimation.xml <?xml version=”1.0” encoding=”utf-8”?> <animation-list xmlns:android=”http://schemas.android.com/apk/res/android” animation:oneshot=”false” > //false为循环播放,true为类似于View动画的setFillAfter效果 <item android: drawable =”@ drawable/ drawable 1” android:duration=” 200”> <item android: drawable =”@ drawable/ drawable 2” android:duration=” 200”> </animation-list> //在代码里加载动画设置并启动动画 view.setBackgroundResource(R.drawable.myanimation.xml); (AnimationDrawable)view.getBackground.start();
3. 属性动画
View动画的那四种效果有很明显的缺点,绘制出来的效果其实并没有真正改变View的属性,即left、top、right和bottom的值,只是系统临时绘制的结果。这样View的点击位置并没有发生变化。针对这个问题,从Android3.0开始属性动画应运而生。
属性动画本质是通过改变新增的属性(如平移translationX/Y、缩放scaleX/Y、旋转rotationX/Y等)并刷新屏幕来实现动画效果,并且实现点击位置的实时改变。但是属性动画仍然不会修改原始的上下左右四个值。最后需要注意的是,属性动画不止用于View,还可以用于任何对象。
下面介绍与属性动画相关的类和方法:
3.1 setTranslationX方法
该方法直接更改view属性的方法,因为有时候不需要使用动画效果。
view.setTranslationX(x);//3.0以后 ViewHelper.setTranslationX(view,x);//3.0以前通过NineOldAndroid库实现
3.2 ValueAnimator类
ValueAnimator只定义和执行动画流程,并没有直接操作属性值的逻辑,需要添加动画更新的监听,并在onAnimationUpdate()中执行自定义的动画逻辑。 [java] view plain copy 在CODE上查看代码片派生到我的代码片 ValueAnimator animator = ValueAnimator.ofInt(1, 100); //定义动画,相当于1秒内数100个数 animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation){ float fraction = animation.getAnimatedFraction();//动画进度值0-1 //整型估值器帮我们计算了start+(end-strat)*fraction,并设置给控件的宽度 view.getLayoutParams().width = new IntEvaluator().evaluate(fraction,start,end) //不需要set方法 view.requestLayout(); } }); animator.setDuration(1000).start();
3.3 ObjectAnimator类
ObjectAnimator继承自ValueAnimator,它允许直接改变view的属性,下面通过一个例子介绍。
//x轴方向缩放的例子 ObjectAnimator animator = ObjectAnimator.ofFloat(view,”scaleX”,2.0f); animator.setDuration(1000); animator.setStartDelay(1000); animator.start();
大多数的情况使用ObjectAnimator就足够了,因为它不用像ValueAnimator那样自己写动画更新的逻辑,但是ObjectAnimator有一定的限制——它需要目标属性提供指定的处理方法(譬如提供get/set方法),这是因为ObjectAnimator的原理是不停的调用set方法更新属性值,并且如果我们没有传递初始值,系统会直接调用get方法获取值。而上面3.2中介绍过的ValueAnimator则不直接操作属性值,所以要操作对象的属性可以不需要se/get方法,你完全可以通过当前动画的计算去修改任何属性。
针对这个问题,官方推荐我们用一个类包装原始对象,间接为其提供get/set方法,实现起来很简单,实例如下:
ViewWrapper wrapper = new ViewWrapper(view); ObjectAnimator.ofInt(view,”width”,200).setDuration(1000).start(); private static class ViewWrapper{ private View myView; public ViewWrapper(View view){ myView = view; } public int getWidth(){ return myView.getLayoutParams().width; } public int setWidth(int width){ myView.getLayoutParams().width = width; myView.requestLayout(); } }
3.4 ViewPropertyAnimation类
ViewPropertyAnimation是NineOldAndroid库中的类,简化了ObjectAnimator类的操作,并且NineOldAndroid库兼容了3.0以前的Android版本。下面经过一个例子介绍。
//x轴方向缩放的例子,效果同3.3 ViewPropertyAnimation.animate(view).scaleX(2.0f).setDuration(1000) .setInterpolator(new OvershootInterpolator()) .setStartDelay(1000).start();
3.5 AnimationSet类
动画集合,提供把多个动画组合成一个组合的机制,并可设置动画的时序关系,如同时播放、顺序播放或延迟播放。具体使用html" target="_blank">方法比较简单,如下所示:
ObjectAnimator objectAnimator1= ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0f); ObjectAnimator objectAnimator2= ObjectAnimator.ofFloat(view, "translationY", 0f, 30f); ObjectAnimator objectAnimator3= ObjectAnimator.ofFloat(view, "translationX", 0f, 30f); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.setDuration(5000); animatorSet.setInterpolator(new LinearInterpolator()); // animatorSet.playTogether(objectAnimator1, objectAnimator2. objectAnimator3); //三个动画同时执行 // 12同时执行,3接着执行 animatorSet.play(objectAnimator1).with(objectAnimator2); animatorSet.play(objectAnimator3).after(objectAnimator2); animatorSet.start();
4. 插值器总结
4.1 系统已经提供给我们的插值器
各种插值器都是实现了Interpolator接口,下面来看一下系统已经提供给我们直接使用的插值器。
4.2 自定义插值器
Interpolator都实现了Interpolator接口,而Interpolator接口又继承自TimeInterpolator,TimeInterpolator接口定义了一个由系统调用的getInterpolation(float input)方法,其中参数input代表动画完成进度,在0和1之间。我们自定义插值器只需要实现Interpolator接口并覆写getInterpolation()方法即可实现自定义的动画效果。
如下就是一个动画始末速率较慢、中间加速的AccelerateDecelerateInterpolator插值器:
public class AccelerateDecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { ...... public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } ...... }
5. 动画监听器
我们在平时开发过程中,经常要监听动画完成的时机以继续业务逻辑,那么我们可以通过给动画集合设置AnimationListener监听器来实现。分别可以监听动画开始、结束、取消以及重复播放。
//监听动画完成 animationSet.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationCancel(Animation animation) {} });
最后若想监听动画中每一帧的回调,我们可以设置AnimatorUpdateListener监听器并重写其onAnimationUpdate()方法即可。
至此关于Android动画的知识总结完毕。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
主要内容:本节引言:,1.帧动画概念以及用法,2.使用示例:,3.本节示例代码和Gif帧提取工具下载,本节小结:本节引言: 从本节开始我们来探究Android中的动画,毕竟在APP中添加上一些动画,会让我们的应用变得 很炫,比如最简单的关开Activity,当然自定义控件动画肯定必不可少啦~而Android中的动画 分为三大类,逐帧动画(Frame)以及补间动画(Tween),还有Android 3.0以后引入的属性动画 (Property),而本节给大家带来的是第一种动画——逐帧动画的一个基本
帧动画模块可以将一系列BK.TextureInfo对象进行播放,构成动画效果。 父类:BK.Sprite 构造函数 BK.AnimationSprite(textureInfoArray) 通过textureInfoArray数组创建一个帧动画对象 手Q版本:7.6.3 textureInfoArray: 参数名 类型 textureInfoArray Array BK.TextureInfo可以
回头看看上一节显示的动画,它们是如何从一个空白的画布或白班变成一个复杂、漂亮的动画的?这些动画是怎么产生的?在变化过程中改变的特殊属性是什么?在回忆中摇晃你的手来表明一些物体应该移动或拉伸是不够的:如果你想要动画脱离你的手进入界面,你需要仔细思考在每一步中会发生什么以及哪些值被操作了。 如果你看一下上一节展示的动画GIF图,以及像CAPPTIVATE.co和其他网站展示的多种动画,并且你对发生了什
本文向大家介绍Android动画 实现开关按钮动画(属性动画之平移动画)实例代码,包括了Android动画 实现开关按钮动画(属性动画之平移动画)实例代码的使用技巧和注意事项,需要的朋友参考一下 Android动画 实现开关按钮动画(属性动画之平移动画),最近做项目,根据项目需求,有一个这样的功能,实现类似开关的动画效果,经过自己琢磨及上网查找资料,终于解决了,这里就记录下: 在Android
主要内容:本节引言:,1.Evaluator自定义,2.Interpolator(补间器),3.ViewPropertyAnimator,4.本节示例代码下载,本节小结本节引言: 上节我们对Android的属性动画进行了初步的学习,相信大家对于属性动画已经不再是 一知半解的状态了,本节我们继续来探究Android属性动画的一些更高级的用法! 依旧贴下郭神的三篇文章~ Android属性动画完全解析(上),初识属性动画的基本用法 Android属性动画完全解析(中),ValueAnimator和O
主要内容:本节引言:,1.属性动画概念叨叨逼,2.ValueAnimator简单使用,3.ObjectAnimator简单使用,4.组合动画与AnimatorListener,5.使用XML来编写动画,6.本节示例代码下载:,本节小结:本节引言: 本节给带来的是Android动画中的第三种动画——属性动画(Property Animation), 记得在上一节8.4.2 Android动画合集之补间动画为Fragment 设置过渡动画的时候,说过,App包和V4包下的Fragment调用setC
对于android新手,我想制作一些平滑的动画。 我在设备上有一个文件,其中包含效果,每个效果都是一个动画。该文件告诉我何时播放效果以及效果持续时间。 问题是我不能链动画师动态设置: 现在我如何从我的AnimatorSet()列表中得到mainAnimatorSet();每个动画从最后一个动画的结尾开始。 这不起作用。谢谢
属性动画 CAAnimationDelegate在任何头文件中都找不到,但是可以在CAAnimation头文件或者苹果开发者文档中找到相关函数。在这个例子中,我们用-animationDidStop:finished:方法在动画结束之后来更新图层的backgroundColor。 当更新属性的时候,我们需要设置一个新的事务,并且禁用图层行为。否则动画会发生两次,一个是因为显式的CABasicAni