响应丝滑动画一篇文章中,分别介绍了作用于普通视图、绘制视图的绘制对象、和界面这三种对象的动画效果,但是都有一些使用的局限性。比如这些动画都只是以屏幕上绘制更新的方式绘制动画,并没有真实改变作用对象的实际位置或属性,这种问题在视图动画中尤为明显,在没有特别设置时,动画结束后的视图状态会还原到动画前,也就是说动画中及动画后的视图对象是没有保存动画中用到的一些属性的。这种情况就需要使用本文所介绍的属性动画了。

属性动画本质是对某个对象的属性提供一组变化更新的属性值,他的作用对象不仅可以是视图和界面,也可以是任何具有上述需求的对象类。在Android3.0 API 11开始的AndroidSDK版本中,定义了android.animation.Animator类作为抽象父类来描述属性动画的结构,并提供了android.animation.ValueAnimator作为只变化属性值的属性动画类、android.animation.ObjectAnimator可以变化属性值并更新到对象属性的属性动画类、和android.animation.AnimatorSet包含多个属性动画集合的属性动画类。

与普通动画类似,属性动画同样可以在资源文件中静态声明,也可以在代码中动态声明,但是由于其作用对象可以是任何对象,而且属性动画的优势在于为作用对象的属性提供一组变化的属性值,所以属性动画只能在需要绑定作用对象的代码位置动态使用。由于静态声明的属性动画可以针对多个对象使用,在开发过程中推荐使用静态声明+动态使用的方式。

只变化属性值的属性动画类

ValueAnimator作为最核心的属性动画类,可以调用ValueAnimator.ofArgb(int... values)ValueAnimator.ofFloat(float... values)ValueAnimator.ofInt(int... values)ValueAnimator.ofObject(TypeEvaluator evaluator, Object... values)系列静态方法,获取初始化后的实例化对象。其中的参数 values 是可变长参数,作为可变化属性值的范围区间。而参数 evaluatorandroid.animation.TypeEvaluator估值器接口的实现类,用以计算估计属性值的具体变化数值的类。而AndroidSDK中已经定义了上述系列静态方法前三种类型对应的估值器子类,分别是android.animation.ArgbEvaluatorandroid.animation.FloatEvaluatorandroid.animation.IntEvaluator,除此之外还有计算二维坐标系的估值器android.animation.PointFEvaluator和计算矩形坐标的估值器android.animation.RectEvaluator。另外,在实际开发中针对作用对象要变化的属性值类型不同,也可以自定义实现TypeEvaluator接口的估值器。

这里提到的ArgbEvaluator是用以计算颜色的 ARGB 色值估值器,与Android系统定义的屏幕坐标类似,这里的 ARGB 色值也是一套系统颜色规范。在Java中int类型是用4个字节存储的,这4个字节按顺序从大端到小端,刚好分别表示Alpha(颜色值中的透明度),Red(颜色值中的红色值),Green(颜色值中的绿色值),Blue(颜色值中的蓝色值),每个字节的数值可以表示范围是[ 0x0, 0xFF ],所以用十六进制表示颜色值中的纯红色为 0xFFFF0000 ,纯黑色为 0xFF000000 ,纯白色为 0xFFFFFFFF ,而完全透明色为 0x000000000x00FFFFFF 之间的任一值。也可以借助android.graphics.Color类使用已经定义的颜色值和系统颜色规范的相关方法。

在创建ValueAnimator实例化对象后,

可以调用setDuration(long duration)设置完成一次动画效果的持续时间,单位为 ms 毫秒。

调用setRepeatCount(int value)设置完成一次动画效果后的重复次数,默认 value = ValueAnimator.INFINITE 为无限循环。

调用setRepeatMode(int value)设置在完成一次动画效果后重复时的动画效果,其 value 只能为

ValueAnimator.RESTART 表示从头开始重新完成一次一模一样的动画效果,

ValueAnimator.REVERSE 表示从上次动画结尾开始完成一次倒放的动画效果。

调用 setInterpolator(TimeInterpolator value)设置动画效果的时间插值器。与上面的估值器定义结构类似,参数 valueandroid.animation.TimeInterpolator插值器接口的实现类,用以确定每次更新动画效果的时间。同样的,AndroidSDK已经定义了一系列插值器,包括但不限于持续加速插值器android.view.animation.AccelerateInterpolator、持续减速插值器android.view.animation.DecelerateInterpolator、线性匀速插值器android.view.animation.LinearInterpolator等,同样在实际开发中针对动画效果展示时间进度,也可以自定义实现TimeInterpolator接口的插值器。

最终在需要启动当前属性动画的位置调用start()即开始播放当前动画效果,如果不想在调用属性动画的启动方法后立即执行相关动画效果,可以在启动方法之前调用setStartDelay(long startDelay)设置延时动画的延长时间,单位是 ms 毫秒。

ValueAnimator是根据TypeEvaluator估值器来更新属性值的,而更新的时间则是由TimeInterpolator插值器决定的,那么怎么才能拿到每次更新后的属性值呢?这里就可以用调用ValueAnimator对象的addUpdateListener(ValueAnimator.AnimatorUpdateListener listener)方法添加属性动画更新监听,在AnimatorUpdateListener类中重写onAnimationUpdate(ValueAnimator animation)方法,该方法中的参数animation即更新后的属性动画对象,通过调用animation.getAnimatedValue()来接收每次更新后的属性值,并可以将更新后的属性值赋值给需要属性动画的对象中。

也可以在资源文件中静态定义属性动画,在 res/animator 目录下,定义xml格式的属性动画资源文件,该资源文件内以<animator />为根标签,其中可以设置android:duration作为完成一次动画效果的持续时间等一系列属性,与代码中动态设置的相关方法类似。之后在代码使用位置加载该资源文件,通过调用AnimatorInflater.loadAnimator(Context context, int id)的静态方法,参数context作为调用位置所在的上下文环境,参数id则是要加载的属性动画类型的资源文件名。将得到Animator抽象类的返回结果,根据所加载资源文件中的根标签名判断,如果与<animator />一致,则可将返回的Animator抽象类直接转换为ValueAnimator类型的对象。

可变化属性值并更新到对象属性的属性动画类

ObjectAnimator作为ValueAnimator的子类,定义和使用方式都有类似的地方,只是ObjectAnimator类中封装了属性动画的更新监听方法,因此只要绑定对象及其要变化的属性,在属性动画每次变化属性值时,都会主动将属性值更新到绑定对象的相关属性上。

因此在初始化实例对象时需要调用ofArgb(Object target, String propertyName, int... values)ofFloat(Object target, String xPropertyName, String yPropertyName, Path path)ofInt(T target, Property<T, Integer> property, int... values)ofObject(T target, Property<T, V> property, TypeConverter<PointF, V> converter, Path path)等系列静态方法。

其中参数 target 即为要绑定的动画效果作用对象;

参数 propertyNametarget 对象中的某个属性,而且该属性必须要有符合驼峰命名规则的 getset 方法;

参数 values 仍然作为可变化属性值的范围区间;

参数 path 作为android.graphics.Path类,则表示一段动画效果的执行路径,以此替换参数 values 表示的单一变化区间;

参数 property 作为android.util.Property抽象类,同样描述某种属性类型,以此替换String类型的参数 propertyName

参数 converter 作为android.animation.TypeConverter抽象类,与上文的参数 property 同时使用,当 property 中声明的属性类型与实际变化更新的属性值不一致时,使用参数 converter 所表示的强制类型转换方式。

在创建实例化对象后,ObjectAnimator有与ValueAnimator一致的setXXX()getXXX()系列方法,另外还有setTarget(Object target)方法可以直接绑定要变化属性值的目标对象,同时有setPropertyName(String propertyName)setProperty(Property property)两种调用方法,都能实现对目标对象中的目标属性的绑定。

最后仍然是在需要启动当前属性动画的位置调用start()开始播放当前动画效果。

在资源文件中静态定义时,同样在 res/animator 目录下,定义xml格式的属性动画资源文件,不过该资源文件内根标签为<objectAnimator />以标记关联对象的属性动画,其中的属性设置不仅与只变化属性值的ValueAnimator对应的<animator />标签中的属性一致,还可单独设置android:propertyName绑定属性名称。之后同样可以在代码中调用AnimatorInflater.loadAnimator(Context context, int id)静态方法加载当前属性动画资源文件,同样地,针对得到的Animator抽象类的返回结果,根据所加载资源文件中的根标签名判断,如果与<objectAnimator />一致,则可将返回的Animator抽象类直接转换为ObjectAnimator类型的对象。

包含多个属性动画集合的属性动画类

SetAnimator是将一系列上述单独的属性动画组合起来的属性动画合集,其使用目的主要是为了讲不同的属性动画按照同一条时间线整理播放,因此其相关方法主要与其中子动画的播放顺序相关。

通过直接创建SetAnimator()构造方法可以获得SetAnimator实例化对象。

得到的对象调用playTogether(Animator... items)方法可以在同一段时间内播放添加的子动画,

调用playSequentially(Animator... items)方法可以将其中的子动画按照添加顺序播放,

而这两个系列方法中的可变长参数 items 即是要添加的系列子动画对象。

也可以将得到的对象调用play(Animator anim)方法,参数 anim 为添加的基本动画,返回android.animation.AnimatorSet.Builder类型,可以调用该类的before(Animator anim)方法设置针对基本动画之前播放的动画 anim 、调用该类的with(Animator anim)方法设置与基本动画同时播放的动画 anim 、调用该类的after(Animator anim)方法设置针对基本动画之后播放的动画 anim 、以及该类的after(long delay)方法设置在基本动画之后延时 delay 毫秒之后继续播放之后动画。

最后仍然是在需要启动当前属性动画的位置调用start()开始播放当前动画效果。

在资源文件中静态定义时,同样在 res/animator 目录下,定义xml格式的属性动画资源文件,在资源文件内根标签为<set></set>以标记为集合属性动画,该标签内可以设置属性android:ordering,其值只能为默认的together表示子动画同时执行,或者为sequentially表示子动画按顺序执行。在<set></set>标签内部,可以嵌入上述<animator /><objectAnimator />两种属性动画标签。同样可以在代码中调用AnimatorInflater.loadAnimator(Context context, int id)静态方法加载当前属性动画资源文件,同样地,针对得到的Animator抽象类的返回结果,根据所加载资源文件中的根标签名判断,如果与<set></set>一致,则可将返回的Animator抽象类直接转换为AnimatorSet类型的对象。

Android系统编程入门系列之界面Activity响应多元的属性动画的更多相关文章

  1. Android系统编程入门系列之界面Activity响应丝滑的传统动画

    上篇文章介绍了应用程序内对用户操作响应的相关方法位置,简单的响应逻辑可以是从一个界面Activity跳转到另一个界面Activity,也可以是某些视图View的相对变化.然而不管是启动一个界面执行新界 ...

  2. Android系统编程入门系列之界面Activity绘制展示

    上篇文章介绍了界面Activity的启动方式和生命周期,本篇将继续介绍在界面Activity中的内容是如何绘制展示给用户的. 在Android系统上运行新创建的界面Activtiy,给用户展示的是空白 ...

  3. Android系统编程入门系列之界面Activity交互响应

    在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...

  4. Android系统编程入门系列之加载界面Activity

    上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...

  5. Android系统编程入门系列之应用环境及开发环境介绍

        作为移动端操作系统,目前最新的Android 11.0已经发展的比较完善了,现在也到了系统的整理一番的时间,接下来的系列文章将以Android开发者为中心,争取用归纳总结的态度对初级入门者所应 ...

  6. Android系统编程入门系列之硬件交互——多媒体摄像头

    多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...

  7. Android系统编程入门系列之加载服务Service

    之前几篇文章简单梳理了在Android系统的四大组件之一,最主要的界面Activity中,使应用程序与用户进行交互响应的相关知识点,那对于应用程序中不需要与用户交互的逻辑,又要用到哪些内容呢?本文开始 ...

  8. Android系统编程入门系列之服务Service齐头并进多线程任务

    在上篇文章中初步了解了Android系统的四大组件之一的服务Service,在服务内可以执行无用户交互的耗时操作任务,但是包括之前关于界面系列文章在内,生命周期方法都是在主线程内被系统回调的.如果直接 ...

  9. Android系统编程入门系列之广播接收者BroadcastReceiver实现进程间通信

    在前边几篇关于Android系统两个重要组件的介绍中,界面Activity负责应用程序与用户的交互,服务Service负责应用程序内部线程间的交互或两个应用程序进程之间的数据交互.看上去这两大组件就能 ...

随机推荐

  1. Echarts的使用教程

    项目中需要使用图表,最初使用的.NET自带的MSChart控件,做出来的效果不太好,所以又使用了Echarts控件. MSChart源码放在最后,可自行下载查看. Echarts是一个基于 JavaS ...

  2. Zookeeper 面试题(持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  3. oracle中job无法正常运行,如何排查

    1.生产环境Oracle中的job无法正常运行 select * from dba_jobs_running;(查看正在运行的job) 2.select * from dba_jobs(查看job历史 ...

  4. AliCloudDenoise 语音增强算法:助力实时会议系统进入超清音质时代

    近些年,随着实时通信技术的发展,在线会议逐渐成为人们工作中不可或缺的重要办公工具,据不完全统计,线上会议中约有 75% 为纯语音会议,即无需开启摄像头和屏幕共享功能,此时会议中的语音质量和清晰度对线上 ...

  5. Java 读取Word表格中的文本和图片

    本文通过Java程序来展示如何读取Word表格,包括读取表格中的文本和图片.下面是具体实现的步骤和方法. 1. 程序环境准备 代码编译工具:IntelliJ IDEA Jdk版本:1.8.0 测试文档 ...

  6. SAI常用快捷键大全

    一.默认常用工具快捷键如下: N 铅笔 B 喷枪 V 笔 X 前/背景色切换 - 前景色与透明色切换 C 水彩笔 A 选区笔 S 选区擦 D 清空当前图层 F 向下转写 (当前图层内容合并至下层,该层 ...

  7. App免责声明

    一切移动客户端用户在下载并浏览xxxAPP软件时均被视为已经仔细阅读本条款并完全同意.凡以任何方式使用本APP,或直接.间接使用本APP资料者,均被视为自愿接受本网页相关声明和用户服务协议的约束. x ...

  8. 二、JavaSE语言基础之常量与变量

    1.常量   所谓常量值的是数据处理过程中值不能更改的数据. 2.变量   所谓变量值的是运算过程中值可以改变的数据,类似于代数中的未知数.   在Java语言中,使用变量时必须遵循先定义,而后赋值, ...

  9. 11、gitlab和Jenkins整合(2)

    5.补充: (1)构建说明: 1)Jenkins会基于一些处理器任务后,构建发布一个稳健指数 (从0-100 ),这些任务一般以插件的方式实现. 2)它们可能包括单元测试(JUnit).覆盖率(Cob ...

  10. Linux基础 -03

    2.2.3 head-tail 命令 #------head #head pass #查看头部内容,默认前10行 #head -n5 pass #查看头部前5行,使用-n指定 #-------tail ...