android 属性动画变大,Android PropertyAnimation 属性动画(一)初探

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

前言

相对于静态的页面,动画往往能更直观地表达所需的信息,在UI开发过程中起着相当大的作用。

Android为我们提供了一系列实现动画效果的方法,PropertyAnimaiton是最常见也是最实用的一种,如同它的名字一样,它的实现方式是通过改变对象的一系列属性值来改变对象的状态, 例如动态地改变绘制的位置就可以实现绘制物体的移动效果,动态地改变对象的显示状态可以实现闪烁效果。

Animator概览

Android提供的实现属性动画的工具是android.animation.Animator这个类,它的使用需要配合animation包下的其他工具类,这个类的功能是什么,我们要如何使用它来实现属性动画呢?

我们可以将Animator理解为Android为我们提供的一个按我们的需要在一定时间段内连续地计算并返回值的工具,这个值可以是通用的整型、浮点型,也可以是我们自定义的类型。

我们可以设置返回值的范围,并可以控制值变化的快慢,例如实现自由落体下落的物体时我们需要让高度值以一个越来越快的速度降低。

这里的连续需要注意,实际上是不可能产生真正意义上的连续值的,但是如果在绘制过程中计算这个值的速度小于绘制一帧所需要的时间,那么我们就可以在视觉上认为这个值是在连续改变的。这一点也是理解其作用的关键:我们很难去写出一个可以随时获取连续值的工具,而Animator正是一个满足我们这个需求的一个通用工具。

通过将Animator与View的绘制过程结合,就可以实现绝大多数的动画效果, 但是Animator也不只局限在使用在绘制动画,只要是有相似需求的地方都可以使用它来实现, 同时由于属性动画只针对属性进行修改,与被修改对象之前几乎没有耦合,不需要对被修改对象作出改变,可以设置方式也多种多样,这些都是动画的另一种实现方法ViewAnimator所无法做到的,所以我属性动画是现在实现动画效果的普遍做法。

使用Animator

Animator子类

下面就来看看如何使用Animator满足我们的需求。

我们使用Animator可以分为两个步骤,一是进行数值的计算,二是将计算出的数值设置到对应的对象上。而Animator有着三个子类:ValueAnimator ObjectAnimator AnimatorSet。ValueAnimator实现了上述过程的第一个步骤:进行数值的计算。第二个步骤则需要我们重写它的回调在值发生改变时候手动地为对象更新属性值。

ObjectAnimator则在其基础上进行了进一步的封装,加入了一些方法使得它可以绑定一个对象,在数值改变的同时对对象的属性进行更新。

AnimatorSet可以对Animator进行组合,让它们之间进行联动,例如可以设置一个动画根据另一个动画的状态来决定是否开始、暂停或停止。

可以看到,ValueAnimator提供了一个Animator最核心的内容,也是使用中最为灵活的一个。ObjectAnimator由于绑定了相应的对象,在使用上会受一些限制。AnimatorSet专用于需要组合动画的场景。

ValueAnimator

在这篇博客中,我们关注最为核心的ValueAnimator。

关键属性

ValueAnimator对象内部维护了一系列属性来保存所需的各种信息。Duration:动画的持续时间,通过setDuration()方法设置

Repeat count and behavior:重复计数与重复模式,我们可以通过设置这两个属性来控制动画是否重复以及重复的次数,通过setRepeatCount()与setRepeatMode()方法设置

Frame refresh delay:帧刷新延迟,也就是计算两帧动画之间的间隔时间,但这个时间只是Animator尽力去保持的值,具体的间隔时间会由于系统负载与性能的不同而不同,同时设置它的方法为一个静态方法:ValueAnimator.setFrameDelay(),会被设置到所有的Animator上,这是因为这些Animator都在同一个时间循环中。这个属性也有可能会被忽略如果动画系统采用了内部的计时来源,例如vsync来计算属性。同时这个方法需要在与start()方法相同的进程中调用

Time interpolation:时间插值器,是我们实现不同动画效果的关键,每一时刻所返回的数值由它决定,后文会详细讲

初始化与TypeEvaluator

ValueAnimator对象的构造函数只由内部使用,获取ValueAnimator对象的方法是调用它的工厂方法:

ValueAnimator.ofArgb()

ValueAnimator.ofInt()

ValueAnimator.ofFloat()

ValueAnimator.ofObject()

ValueAnimator.ofPropertyValuesHolder() //本篇未涉及,下一篇进行讲解

前三个可以看作是ValueAnimator为我们提供的初始化方式,它们的参数都是对应类型的长度可变参数:(Type ...values),我们需要提供一个以上的参数,ValueAnimator最终提供的值会在这些值之前变动。

一般情况下这里提供的Argb(用于颜色值的变化)和整型、浮点值基本可以满足我们的需求,但是某些时候我们需要结果是我们自定义的一些对象,这个时候就需要用到TypeEvaluator<>接口了,与这个接口对应的工厂方法是ValueAnimator.ofObject():1

2ValueAnimator (TypeEvaluator evaluator,

Object... values)

这里的可变参数类型变为了Object,同时还需要我们提供一个TypeEvaluator<>,用于“告诉”Animator如何返回这个Object值。

TypeEvaluator<>接口并不复杂,只有一个方法需要我们重写:1

2

3T evaluate (float fraction,

T startValue,

T endValue)

startValue与endValue非常好理解,就是我们在获取Animator时指定的值的起始值和结束值。类型与返回类型一致,当然都是我们自定义的类型。

这里的fraction就是决定我们最终返回值的关键参数。我们可以把这个fraction理解为animator提供给我们的最终的数值改变的比例,以小数表示,小于0表示低于startValue,大于0表示超出endValue,0-1之间表示在startValue与endValue之间。我们要做的就是把这个值转换为在起始和结果范围之间的合适的对象值。

例如,对于基本的浮点类型,默认的FloatEvaluator是这样的:1

2

3

4public Float evaluate(float fraction, Number startValue, Number endValue){

float startFloat = startValue.floatValue();

return startFloat + fraction * (endValue.floatValue() - startFloat);

}

可以看到,就是相当于把fraction所表示的比例“投射”到了我们所需要的数据对象上,这里是浮点类型。如果使用我们的自定义类型,我们必须为自己的类型定义这样的操作。

注意:这里要求我们必须将fraction线性地反应到对应的类型上,因为fraction反映的是最终的动画进度,我们必须如实地按照这个进度改变我们的属性,所以需要将result = x0 + t * (x1 - x0)`这样的形式反映到我们自己的对象上。

自定义了TypeEvaluator以后就可以作为参数使用在上面的obObject()工厂方法中了。

插补细分器(Interpolators)

下面介绍使用ValueAnimator控制值变化过程中最为重要的一个概念:插补细分器(Interpolators)。

它实际上是一个关于时间的函数, 根据时刻的不同来返回不同的值,进而来控制最后的输出的值。那么它是如何表示的呢?

系统为我们提供了一系列预置的Interpolators,以较常用的LinearInterpolater为例,顾名思义,它是一个线性的插补细分器,意味着输入与输出呈线性关系:1

2

3public float getInterpolation(float input){

return input;

}

输入输出的关键函数就是这个getInterpolation()了,可以看到,参数与返回值都是float类型,input的值在0-1之间,结合前面,我们可以很容易理解,这个input就是一个以0-1之间的小数表示的过去的时间值,例如整个动画是1000ms,当input为0.25的时候意味着现在的时间过去了250ms。

而返回值就是经过我们的转换,表示出的动画应该进行的时间的比例,这里由于是线性的,所以可以直接返回input,这个值最后会到哪里呢?自然就是给我们前面介绍的TypeEvaluator。下面一段源码展示了这个过程:1

2

3

4

5if (mInterpolator != null) {

fraction = mInterpolator.getInterpolation(fraction);

}

return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(),

mLastKeyframe.getValue());

作为getInterpolation()参数的fraction代表着过去的时间比例,这里调用我们设置的Interpolator来更新这个fraction,现在这个fraction表示的就是动画已经进行的比例,下一步就要根据它来获取对应的对象值(调用了我们之间谈到过的evaluate()方法,这里的KeyFrame的概念会在之后的博客讲到),后面的两个参数就是传递给evaluate的起始与结束范围。

最终,我们就获得了一个按照我们设定的Interpolator返回的动画属性值。

如果想要实现加速效果呢?Android同样为我们提供了现成的AccelerateInterpolator:1

2

3

4

5

6

7public float getInterpolation(float input){

if (mFactor == 1.0f) {

return input * input;

} else {

return (float)Math.pow(input, mDoubleFactor);

}

}

同样很简洁,这里用到了mFactor与mDoubleFactor分别表示我们在构造函数里面设置的指数值:1

2

3

4public AccelerateInterpolator(float factor){

mFactor = factor;

mDoubleFactor = 2 * mFactor;

}

如果我们设置的为1,会返回input的平方,其他值则会返回input的mDoubleFactor次方,使得动画属性可以以不同的函数曲线形式变化。

如果我们要实现自己的Interpolator呢?只需要实现TimeInterpolator接口,这个接口只需要我们实现一个getInterpolation方法。我们可以根据input值返回不同的值来返回不同的值表示动画的进度。

注意:返回值的范围不一定要在0-1之间,小于0或大小1的值可以表示超出预设范围的目标值。

这篇博客到此结束,在下一篇博客中将会以一个绘制自由落体的弹跳小球的示例来演示如何使用Animator与介绍它的回调函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/270881.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android stadio svn 使用技巧

有时候有这样的需求&#xff1a; 就是我一次要改很多的需求&#xff0c;然后代码要分开提交&#xff0c;那么怎么办&#xff1f; 提交的时候一个一个的点开看&#xff1f; 比如&#xff1a;这次改的还没有提上去&#xff0c;又来了一个需求&#xff0c;怎么区分呢 新建一个ac…

用扫地机器人楼下吵吗_扫地机器人到底好不好用?说说我两年的使用体验!

原标题&#xff1a;扫地机器人到底好不好用&#xff1f;说说我两年的使用体验&#xff01;说到扫地机器人绝大部分人都非常陌生&#xff0c;因为我国目前还处在扫地机器人发展初期阶段&#xff0c;连一线城市普及率都只有5%&#xff0c;所以非常理解大家对新事物的恐惧和排斥&a…

SQLServer常用的日期和时间函数梳理

今天给大家分享一下SQLServer常用的日期和时间函数知识笔记&#xff0c;希望对大家能有所帮助&#xff01;1、DATEADD(datepart,number,date)作用&#xff1a;返回给指定日期加一个时间间隔后新的datetime值参数说明&#xff1a;datepart&#xff1a;指定为日期的哪部分增加数值…

树二叉树二叉搜索树

树&二叉树 树是由节点和边构成&#xff0c;储存元素的集合。节点分根节点、父节点和子节点的概念。 二叉树binary tree&#xff0c;则加了“二叉”&#xff08;binary&#xff09;&#xff0c;意思是在树中作区分。每个节点至多有两个子&#xff08;child&#xff09;,left…

努比亚连续按下android版本,虚惊一场!努比亚Z17的Android 9.0真的不远了

01努比亚Z17将推送安卓9.0中关村在线消息&#xff1a;前不久&#xff0c;有消息传出努比亚Z17开发者版本系统将停止更新&#xff0c;并将永远停留在Android 7.0之后&#xff0c;引起了众多牛仔们的一篇叹息。大家纷纷在惋惜的同时&#xff0c;也着实对努比亚的做法有些不理解。…

websocket 西部数码php_网页实时聊天之PHP实现websocket

前言websocket 作为 HTML5 里一个新的特性一直很受人关注&#xff0c;因为它真的非常酷&#xff0c;打破了 http “请求-响应”的常规思维&#xff0c;实现了服务器向客户端主动推送消息&#xff0c;本文介绍如何使用 PHP 和 JS 应用 websocket 实现一个网页实时聊天室&#xf…

String有两种赋值方式

String有两种赋值方式&#xff0c;第一种是通过“字面量”赋值。 String str "Hello"; 第二种是通过new关键字创建新对象。 String str new String("Hello");

SQLServer知识:sqlcmd用法笔记

今天给大家介绍sqlcmd用法笔记&#xff0c;希望对大家能有所帮助&#xff01; 1、介绍 sqlcmd是一个 Microsoft Win32 命令提示实用工具&#xff0c;可以通过该命令工具实现SQL语句、脚本的执行&#xff0c;并且可以实现脚本任务的自动化。 2、使用场景 2.1 针对大文件脚本的执…

aes c android ios,AES加密在iOS和Android中产生不同的结果

尝试使用AES128算法加密样本数据,在Android和iOS中使用CBC和PKCS7填充,但结果不同:(Android代码&#xff1a;private static final byte[] KEY { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};int srcBuffSiz 1024;byt…

树形DP+树状数组 HDU 5877 Weak Pair

1 //树形DP树状数组 HDU 5877 Weak Pair2 // 思路&#xff1a;用树状数组每次加k/a[i]&#xff0c;每个节点ansSum(a[i]) 表示每次加大于等于a[i]的值3 // 这道题要离散化4 5 #include <bits/stdc.h>6 using namespace std;7 #define LL long long8 typedef pair<int…

mysql一直拒绝登录_mysql 登录错误:1045 (28000)访问被拒问题

关键条目&#xff1a;ERROR 1045(28000): Access deniedforuserrootlocalhost(using password: YES)这个错误1045(28000)的本质其实就是访问被拒绝&#xff0c;问题原因也很简单&#xff0c;就是用户密码不适用&#xff0c;也可以理解为用户或密码错误。Access deniedforuserro…

SQLServer书写规范梳理

今天给大家分享SQLServer书写规范笔记&#xff0c;希望对大家能有所帮助!1、在名称中仅使用字母、数字和下划线要在名称中仅使用字母、数字和下划线&#xff0c;主要是因为这些字符可以被方便的移植到编程语言中。在应用程序的数据库和编程语言中能够使用相同的属性字段名称&am…

android 屏幕旋转不重新加载,Android webview旋转屏幕导致页面重新加载问题解决办法...

Android webview旋转屏幕导致页面重新加载问题解决办法1. 在create时候加个状态判断protected void onCreate(Bundle savedInstanceState){...if (savedInstanceState null){mWebView.loadUrl("your_url");}...}2. 重载保存状态的函数&#xff1a;Overrideprotected…

visio调整形状位置_VISIO绘图技巧—三相桥式全控整流电路绘制

前些天有网友留言询问如何画三相桥式全控整流电路&#xff0c;一直没时间回复。今天得闲在家&#xff0c;给大家介绍一下如何来画。上图是一个三相桥式全控整流电路原理图&#xff0c;大部分图形元件在VISIO自带的图形库中都能找到&#xff0c;下面来看看如何找出我们需要的绘图…

计算机组成原理——关于数据对齐存储

计算机组成原理——关于数据对齐存储 1. 综述 博客&#xff1a;http://blog.csdn.net/cyxcw1/article/details/9080519(C/C数据边界对齐的注意事项) 对齐&#xff1a;变量的起始地址为其大小的整数倍。如short型占两个字节&#xff0c;其起始地址就要从偶数地址开始。 对齐可以…

电脑术语科普:什么是“显卡交火”?

有时候看到别人在讨论显卡交火的话题&#xff0c;相信大家对显卡交火这个术语了解得也比较少&#xff0c;那么它是什么意思呢? 显卡交火简单的说就是&#xff1a;让两块或者多块显卡在一台机子上协同工作&#xff0c;相比于使用一张显卡图形性能有所提升。 目前主流显卡交火有…

Mac查看本机ip地址

Mac查看本机ip地址 ifconfig | grep "inet" 箭头处为ip地址

python3.4 pip安装_python3.4的pycurl pip安装

我正在安装pycurl for python3.4如果我运行“pip install pycurl”&#xff0c;我有&#xff1a;Downloading/unpacking pycurlRunning setup.py (path:C:\Users\kkw\AppData\Local\Temp\pip_build_kkw\pycurl\setup.py) egg_info for package pycurlPlease specify --curl-dir…

html页面整体变灰,css实现网站整体变灰(兼容火狐)

天下兴亡&#xff0c;匹夫有责。有时候我们可能需要将网站整体变灰&#xff0c;实现方法也很简单。将下面代码加入到 wordpress 主题目录下的 style.css 文件中即可&#xff1a;/* 网站变灰代码 */html{ filter: grayscale(100%); -webkit-filter: grayscale(100%); -moz-filte…