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

属性动画本质是对某个对象的属性提供一组变化更新的属性值,他的作用对象不仅可以是视图和界面,也可以是任何具有上述需求的对象类。在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. 用好idea这几款插件,可以帮你少写30%的代码

    Easycode是idea的一个插件,可以直接对数据的表生成entity,controller,service,dao,mapper,无需任何编码,简单而强大. 1.安装(EasyCode) 我这里的 ...

  2. Android Gradle插件

    目录 什么是Gradle 编写方法 buildSrc 基础概念 Extension 自定义Task Plugin Transformer Gradle用处 好文章 常见问题 Gradle插件练习地址: ...

  3. csp-s模拟测试55(9.29)联「线段树」·赛「??」题「神仙DP」

    T1 联 考试两个小时终于调过了,话说一个傻逼错最后还是静态查出错的..... 大概维护两个懒标记,一个区间覆盖,一个区间异或,然后保证每个区间只会存在一种懒标记. 然后维护区间0的个数,查询时查询那 ...

  4. 裸辞闭关2个月,成功进大厂!吃透这份562页《算法知识手册》,化身offer收割机!

    前言 记得我上本科的时候,我们老师一直跟我们强调:"算法才是编程的灵魂,一定要把算法学好."因为不管你是Java编程爱好者.还是python的忠实粉丝,亦或觉得PHP才是这个世界最 ...

  5. Vue开发项目全流程

    只记录vue项目开发流程,不说明怎样安装node和vue-cli等 确认安装 安装好node之后,可查看是否安装成功,有版本则安装成功.输入node -v 查看vue是否安装成功,有版本则安装成功.输 ...

  6. OSPF 路由协议

    OSPF路由协议 目录 一.OSPF路由协议概述 1.1.内部网关和外部网关协议 1.2.OSPF的工作过程 1.3.OSPF的基本概念 二.OSPF 数据包类型 2.1.OSPF数包 2.2.OSP ...

  7. Centos7一键配置阿里云yum源脚本

    Centos7一键配置阿里云yum源脚本 工作中linux系统经常要配置网络yum,故写了一个简单的配置阿里云yum源的的脚本可以单独使用也可以在做自动化部署的时候调用. #!/bin/bash # ...

  8. JUnit5注解学习指引

    注解(Annotations)是JUnit的标志性技术,本文就来对它的20个注解,以及元注解和组合注解进行学习. 20个注解 在org.junit.jupiter.api包中定义了这些注解,它们分别是 ...

  9. 15 自动发布Java项目(Tomcat)

    #!/bin/bash export PAHT=/usr/local/maven/bin:/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/ ...

  10. oracle查询用户所在表为空的表名

    1 select * from user_tables where num_rows = 0 查询之后发现查询的不全,查询之后发现num_rows为空 select * from user_table ...