Android动画
可以分为3类,分别是:
View Animation(视图动画也叫补间动画)
Drawable 动画
Property Animation(属性动画)
它们组成了Android整个动画体系,它们各有自己的一席之地。通过AnimationHandler类实现UI的更新
View Animation
视图动画,也叫 Tween (补间)动画可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度)。注意该动画对view变换,不涉及到view的属性。所以你平移一个view到新的地方,点击事件等,不会再新的地方触发,而是在老的地方。特别注意:补间动画只能给 View 使用。页面销毁时,会自动回收。
动画的种类Animation 属性详解
通用属性 除了上述属性外还有部分常用方法特定属性介绍
Alpha 属性详解
Rotate 属性详解
Scale 属性详解
Translate 属性详解
AnimationSet 详解(动画组,不是指某个类型动画,而是一个动画的集合)
他继承自 Animation,所以特别注意, 当我们对 set 标签使用 Animation 的属性时会对该标签下的所有子控件都产生影响。如设置duration、repeatCount,是指组内都生效。
XML使用方式
View 类的Anima方法Interpolator 插值器详解
系统提供了许多已经实现的插值器, 具体如下:
使用
自定义Interpolator
Drawable 动画
Drawable 动画其实就是 Frame 动画(帧动画),它允许你实现像播放幻灯片一样的效果,这种动画的实质其实是 Drawable, 所以这种动画的 XML 定义方式文件一般放在 res/drawable/ 目录下。
XML
使用
特别注意:AnimationDrawable 的 start() 方法不能在 Activity 的 onCreate 方法中调运,因为AnimationDrawable 还未完全附着到 window 上, 所以最好的调运时机是onWindowFocusChanged() 方法中。页面销毁时,会自动回收。
Property Animation(属性动画)
Android 3.0 以后引入了属性动画,属性动画可以轻而易举的实现许多 View 动画做不到的事, 上面也看见了,View动画无非也就做那几种事情,别的也搞不定,而属性动画就可以的, 譬如3D旋转一张图片。其实说白了,你记住一点就行,属性动画实现原理就是修改控件的属性值实现的动画。
常用的 View 属性成员:
translationX,translationY:控制View的位置,值是相对于View容器左上角坐标的偏移。
rotationX,rotationY:控制相对于轴心旋转。
x,y:控制View在容器中的位置,即左上角坐标加上translationX和translationY的值。
alpha:控制View对象的alpha透明度值。
属性动画的抽象基类Cloneable。我们看下他的实现子类:
Android 属性动画提供了以下属性:
Duration:动画的持续时间;
TimeInterpolation:定义动画变化速率的接口,所有插值器都必须实现此接口,如线性、非线性插值器;
TypeEvaluator:用于定义属性值计算方式的接口,有 int、float、color 类型,根据属性的起始、结束值和插值一起计算出当前时间的属性值;
Animation sets:动画集合,即可以同时对一个对象应用多个动画,这些动画可以同时播放也可以对不同动画设置不同的延迟;
Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为 10ms,最终刷新时间还受系统进程调度与硬件的影响;
Repeat Country and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以让此动画一直重复,或播放完时向反向播放;
XML实现
结合使用java实现
1、ObjectAnimator: 继承自 ValueAnimator,允许你指定要进行动画的对象以及该对象的一个属性。该类会根据计算得到的新值自动更新属性。其实ObjectAnimator最根本的是改变属性,在属性改变的过程中对view进行各种处理达到动画的效果。
这样就达到了一个文字变更的效果2、PropertyValuesHolder: 多属性动画同时工作管理类。有时候我们需要同时修改多个属性,那就可以用到此类,具体如下:
3、ValueAnimator: 属性动画中的时间驱动,管理着动画时间的开始、结束属性值,相应时间属性值计算方法等。包含所有计算动画值的核心函数以及每一个 动画时间节点上的信息、一个动画是否重复、是否监听更新事件等,并且还可以设置自定义的计算类型。
特别注意:
ValueAnimator 只是动画计算管理驱动,设置了作用目标,但没有设置属性,需要通过 updateListener 里设置属性才会生效。
4、AnimationSet: 动画集合,提供把多个动画组合成一个组合的机制,并可设置动画的时序关系,如同时播放、顺序播放或延迟播放。具体使用方法比较简单。
5、Evaluators (估值器)相关类解释: Evaluators 就是属性动画系统如何去计算一个属性值。它们通过Animator 提供的动画的起始和结束值去计算一个动画的属性值。
IntEvaluator:整数属性值。
FloatEvaluator:浮点数属性值。
ArgbEvaluator:十六进制color属性值。
TypeEvaluator:用户自定义属性值接口,譬如对象属性值类型不是 int、float、color 类型, 你必须实现这个接口去定义自己的数据类型
6、Interpolators (差值器)相关类解释:
AccelerateDecelerateInterpolator:先加速后减速。
AccelerateInterpolator:加速。
DecelerateInterpolator:减速。
AnticipateInterpolator:先向相反方向改变一段再加速播放。
AnticipateOvershootInterpolator:先向相反方向改变,再加速播放,会超出目标值然后缓慢移动至目标值,类似于弹簧回弹。
BounceInterpolator:快到目标值时值会跳跃。
CycleIinterpolator:动画循环一定次数,值的改变为一正弦函数: Math.sin(2 * mCycles *Math.PI * input) 。
LinearInterpolator:线性均匀改变。
OvershottInterpolator:最后超出目标值然后缓慢改变到目标值。
TimeInterpolator:一个允许自定义 Interpolator 的接口,以上都实现了该接口。
具体实现见前面几个,一般使用系统默认的差值器就可以了,如果有其他需求可以自定差值器,同视图动画。
属性动画拓展之 ViewPropertyAnimator 动画
View 的 animate() 方法可以得到一个 ViewPropertyAnimator 的属性动画 ,ViewPropertyAnimator 提供了一种非常方便的方法为 View 的部分属性设置动画(切记,是部分属性), 它可以直接使用一个 Animator 对象设置多个属性的动画;在多属性设置动画时,它比上面的ObjectAnimator 更加牛逼、高效, 因为他会管理多个属性的 invalidate 方法统一调运触发,而不像上面分别调用,所以还会有一些性能优化。
ViewPropertyAnimator 的常用方法:
可以把ViewPropertyAnimator 当做是API给你封装好的一些给view使用的方法让你使用
动画动画占用大量内存,如何优化?
帧动画优化
当我们使用Drawable 动画 (AnimationDrawable) 用于实现帧动画。在动画开始之前,所有帧的图片都被解析并占用内存,一旦动画较复杂帧数较多,在低配置手机上容易发生 OOM。即使不发生 OOM,也会对内存造成不小的压力,那么如何来优化呢?有没有什么办法让帧动画的数据逐帧加载,而不是一次性全部加载到内存? SurfaceView 就提供了这种能力。
SurfaceView 屏幕的显示机制和帧动画类似,也是一帧一帧的连环画,只不过刷新频率很高,感觉像连续的。为了显示一帧,需要经历计算和渲染两个过程,CPU 先计算出这一帧的图像数据并写入内存,然后调用OpenGL 命令将内存中数据渲染成图像存放在 GPU Buffer 中,显示设备每隔一定时间从 Buffer 中获取图像并显示。
上述过程中的计算,对于 View 来说,就好比在主线程遍历 View树 以决定视图画多大(measure),画在哪(layout),画些啥(draw),计算结果存放在内存中,SurfaceFlinger 会调用 OpenGL 命令将内存中的数据渲染成图像存放在 GPU Buffer 中。每隔16.6ms,显示器从 Buffer 中取出帧并显示。所以自定义 View 可以通过重载 onMeasure() 、 onLayout() 、 onDraw() 来定义帧内容,但不能定义帧刷新频率。SurfaceView 可以突破这个限制。而且它可以将计算帧数据放到独立的线程中进行利用Bitmap 绘制一帧解析一张将 Bitmap 的解析参数 inBitmap 设置为已经成功解析的 Bitmap 对象以实现复用。
总结:SurfaceView 的特性是在子线程绘制UI的,而且可以自行控制频率等,所以可以避免OOM的问题。
自定义动画优化
移动图片资源至大分辨率目录下,比如xxxhdpi。
动画完成且不再循环展示的部分,相关bitmap释放。
无用对象释放,非透明背景图片采用RGB_565颜色格式,并且将图片的inSampleSize设置为2。
能在初始化中做的事,坚决不在ondraw中做。
能用硬件加速,就别关闭它。
优化算数运算,并尽量从ondraw()中移除算数运算。
属性动画
在相关的生命周期方法中,跟随生命周期的结束,属性动画应及时进行销毁释放。
Scene Transition 过度动画(转场动画)(作为了解用的不多)
有简单的一些实现方法,单一,且无法做一些深入的差值需求(所以导致会生硬),一般用到的比较少。
Scene:场景 ,保存了一个视图层级结构
Scene Scene1 = Scene.getSceneForLayout(root, R.layout.activity_main_part1, this);//得到一个场景
Transition 效果
ChangeBounds:检测View的位置边界创建移动和缩放动画(关注布局边界的变化)
ChangeTransform:检测View的scale和rotation创建缩放和旋转动画(关注scale和ratation的变化)
ChangeClipBounds:检测View的剪切区域的位置边界,关注的是剪切区域Rect rect的变化).
ChangeImageTransform:检测ImageView的ScaleType,并创建相应动画(关注的是ImageView的scaleType)
Fade:根据View的visibility状态的的不同创建淡入淡动画,调整的是透明度(关注的是View的visibility的状态)//通过调整透明度在场景中增添或移除视图
Slide:根据View的visibility状态的的不同创建滑动动画(关注的是View的visibility的状态)//从场景边缘移入或移出视图
Explode:根据View的visibility状态的的不同创建分解动画(关注的是View的visibility的状态)//从场景中心移入或移出视图
AutoTransition:默认动画,ChangeBounds、Fade动画的集合
使用
TransitionManager.go( Scene scene, Transition transition):第一个为必填,第二个为转场效果。不填为默认。
例如:TransitionManager.go(Scene1,new ChangeBounds());
TransitionManager.beginDelayedTransition( final ViewGroup sceneRoot,Transition transition):第一个为必填,第二个为转场效果。不填为默认。
解释 :在执行TransitionManager.beginDelayedTransition()之后,系统会保存一个当前视图树状态的场景,之后当我们改变了View的属性之后(比如重新设置了View位置、缩放、clipe等等)。在下一次绘制时,系统会自动对比之前保存的视图树,然后执行相应动画。
例如:TransitionManager.beginDelayedTransition((ViewGroup)textView1.getRootView());
网友评论