【学习】Android动画解析——类型、使用场景与解析

前言

Android动画可以分三种:View动画 帧动画 属性动画。其实帧动画也属于View动画的一种,只不过它和平移、旋转等常见的View动画在表现形式上略有不同而已。
View动画通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果,它是一种渐进式动画,并且支持自定义。
帧动画通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画,如果图片过大会OOM。
属性动画通过动态改变对象的属性从而达到动画效果,它为API11新特性,低版本只能用兼容库使用它.

View动画

它的作用对象是View,它支持4种动画效果:平移 缩放 旋转 透明度

在这里插入图片描述

要使用View动画,首先要创建动画的XML文件,路径为 res/anim/filename.xml 动画可以由一系列动画组成

View动画常用属性

duration:持续时间
fillAfter:动画结束以后View是否停留在结束位置

< set>

表示动画集合,对应AnimaionSet类,可包含若干动画,并且内部也可以嵌套其他动画集合,以下是属性
interpolator:表示动画集合所采用的插值器,插值器影响动画的速度,也可以不指定
shareInterpolator:表示集合中的动画是否和集合共享同一个插值器,不指定时自动化就需要单独指定所需的插值器或者默认值

< translate>

表示平移动画,可以使一个View在水平和竖直方向完成动画的平移效果以下是属性
from/toX/YDelte:表示x/y的起始/结束值

< scale>

表示缩放动画,它可以使View具有放大或者缩小的动画效果,以下是属性
from/toX/YScale:水平/数值方向的起始/结束值
pivotX/Y:缩放的轴点的x/y坐标,会影响缩放的效果

轴点

轴点是中心点,这时候在水平方向进行缩放的话会导致View向左右两个方向同时进行缩放,如果把轴点设置成View的右边界,那么View就只会向左边进行缩放

< rotate>

标签表示旋转动画,它可以使View具有旋转的动画效果以下是属性
from/toDegress旋转开始/结束的角度
pivotX/Y:旋转的轴点的x/y坐标
在旋转动画中也有轴点的概念,也会影响到旋转的具体效果,View是围绕着轴点进行旋转的。

< alpha>

标签表示透明度动画,可以改变View的透明度以下是属性
from/toAlpha:透明度的起始/结束值

在这里插入图片描述

通过setAnimationListener可以给View动画添加过程监听

在这里插入图片描述

自定义View动画

大致流程
继承Animation抽象类,然后重写initialize和applyTransformation方法,在initialize方法中做一些初始化工作,在applyTransformation进行相应的矩阵变换,很多时候需要采用Camera来简化矩阵变换的过程。因为自定义View动画的过程主要是矩阵变换的过程,在实际开发中很少用到自定义View动画

帧动画

顺序播放一组预先定义好的图片

在这里插入图片描述

View动画的特殊使用场景

1.LayoutAnimation

它作用于ViewGroup,为ViewGroup指定一个动画,这样当它的子元素出场时都会具有这种动画效果以下是属性

delay:子元素开始动画的时间延迟,比如子元素入场动画的时间周期为300ms,该属性设为0.5则表示美俄子元素都需要延迟150ms才能播放入场动画

animationOrder:子元素动画的顺序 normal reverse random,其中normal表示顺序显示,即排在前面的先开始播放,reverse表示逆向播放,random表示随机播放

animation:为子元素指定具体的入场动画

步骤

1.定义LayoutAnimation

在这里插入图片描述

2.为子元素指定具体的入场动画

在这里插入图片描述

3.为ViewGroup指定layoutAnimation

在这里插入图片描述

使用代码实现

在这里插入图片描述

2.Activity的切换效果

切换效果主要用到overridePendingTransition这个方法,这个方法必须在startActivity(Intent)和finish()之后被调用才生效

参数含义
enterAnim:Activity被打开时,所需的动画资源id
exitAnim:Activity被暂停时,所需的动画资源id
Fragment也可以添加切换动画,可以通过FragmentTransaction中的setCustomAnimation方法来添加切换动画。

属性动画

使用属性动画

1.改变一个对象的的属性
ObjectAnimator.ofFloat

2.改变一个对象的背景色属性
ValueAnimator x=ObjectAnimator.ofInt()
setDuration()
setEvaluator

3.动画集合
AnimatorSet set=new AnimatorSet();
set.playTogether(

);

还可以通过XML来定义,属性动画需要定义在res/animator/目录下

在这里插入图片描述

< set>标签对应AnimationSet,< animator>标签对应ValueAnimator,< objectAnimator>标签对应ObjectAnimator

ordering:together表示动画集合中的子动画同时播放,sequentially表示动画集合中的子动画按照前后顺序依次播放

< objectAnimator>属性
propertyName:表示属性动画的作用对象的属性的名称
duration:持续时间
valueFrom/To:表示属性的起始/结束值
startOffest:表示动画的延迟时间,当动画开始后需要延迟多少毫秒才会真正播放此动画
repeatCount:表示动画的重复次数
repeatMode:表示动画的重复模式
valueType:表示propertyNmae所指定的属性的类型,有intTyoe和floatTyoe,如果propertyName指定的是颜色,系统会自动对颜色类型的属性进行处理

在这里插入图片描述

理解插值器和估值器

插值器:根据时间流逝的百分比来计算出当前属性值改变的百分比(LinearInterpolator 线性插值器:匀速动画 AccelerateDecelerateInterpolator 加速减速插值器:两头慢中间快 DecelerateInterpolator 减速插值器:越来越慢)

估值器:根据当前属性改变的百分比来计算改变后的属性值(IntEvaluator 针对整型属性 FloatEvaluator 针对浮点型属性 ArgbEvaluator 针对Color属性)

采用线性插值器和整型估值算法

在这里插入图片描述

属性动画要求对象的属性有set方法和get方法(可选)。我们还可以子当以插值器和估值器,只要派生一个类实现接口就好

属性动画的监听器

两个接口AnimatorListener和AnimatorUpadateListener

AnimatorListener

在这里插入图片描述

它可以监听动画的开始、结束、取消和重复播放,同时还提供了AnimatorListenerAdapter,它是监听器的适配器类,这样我们就可以有选择地实现上面的四个方法

AnimatorUpdateListener

在这里插入图片描述

它会监听整个动画过程,动画是由许多帧组成的,每播放一帧它就会被调用一次。

对任意属性做动画

我们对object的属性abc做动画,如果想要让动画生效,要同时满足两个条件

1.object必须提供setAbc方法,如果动画的时候没有传递初始值,那么还要提供getAbc方法,因为系统要去取abc属性的初始值(不满足直接Crash)

2.setAbc对abc的改变必须能够通过某种方法反映出来,比如会带来ui改变(不满足动画无效果但不会Crash)

问题:对Button改变它的宽度无效

Button虽然提供了getWidth和setWidth方法,但并不是改变视图的大小,这两个方法来自TextView

在这里插入图片描述

它的作用不是设置View的宽度,而是设置TextView的最大宽度和最小宽度,这个和TextView的宽度不是一个东西。TextView的宽度对应XML中Android:layout_width,而TextView还有android:width,这个属性就对应了setWidth方法

解决方法

1.给对象加上set get方法,如果有权限
Button由于是SDK内部实现的,不可行

2.用一个类来包装原始对象,简介提供set get方法
利用ViewWrapper类专门用于包装View

在这里插入图片描述

在这里插入图片描述

3.采用ValueAnimator,监听动画过程,自己实现属性的改变
ValueAnimator本身不作用于任何对象,也就是说直接使用它没有任何动画效果。它可以对一个值做动画,我们可以监听其动画过程,在过程中修改对象的属性值

在这里插入图片描述

在这里插入图片描述

属性动画的工作原理

从ObjectAnimator的start()看起

在这里插入图片描述

在这里插入图片描述

如果当前动画、等待的动画、和延迟的动画中有和当前动画相同的动画,那么就把相同的取消。

super.start()其实是ValueAnimator中的start

在这里插入图片描述

上述代码最终会调用AnimationHandler的start方法,它不是一个Handler而是一个runnable,这个runnable涉及底层交互,先忽略,再看ValueAnimator的aoAnimationFrame方法

在这里插入图片描述

在方法的最后调用了animateBaseOnTime方法

在这里插入图片描述

该方法最后又调用了animateValue方法

在这里插入图片描述

calculateValue方法是计算每帧动画所对应的属性的值。下面着重看一下到底是哪里调用属性的get set方法。在初始化时如果属性的初始值没有提供,则get方法会被调用,查看PropertyValuesHolder的setupValue方法

在这里插入图片描述

可以发现get方法是通过反射来调用的

当动画下一帧来临时,PropertyValuesHolder中的setAnimatedValue方法会将新的属性值设置给对象,调用其set方法,查看下面的源码也可以发现set方法也是通过反射调用

在这里插入图片描述

使用动画要注意的问题

1.OOM问题
主要出现在帧动画中,图片数量较多且图片较大时极易出现OOM

2.内存泄漏
有一类无限循环的动画,这类动画要在活动退出时及时停止,否则导致活动无法释放从而造成内存泄露,View动画没有此问题

3.兼容性问题

4.View动画问题
它是对View的影像做动画并不是真正地改变View状态,有时候可能出现动画完成后View无法隐藏的现象,此时调用view.clearAnimation清除View动画即可

5.不要使用px,尽量使用dp,px在不同设备上有不同效果

6.动画元素的交互
注意动画的前后位置

7.硬件加速
建议开启

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值