本学习笔记主要来自启舰:
http://blog.csdn.net/harvic880925/article/details/50752838
在学习过程中融入了自己的理解和思路。

前面掌握了ValueAnimator、ObjectAnimator动画通过通过ofInt(), ofFloat(), ofObject()等方式创建实例,实际上动画实例的创建还有另外的方法:

//valueAnimator的
public ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values){}
// ObjectAnimator的
public ObjectAnimator ofPropertyValuesHolder(Object target,PropValueHolder... values){}

也就是说ValueAnimator和ObjectAnimator除了通过ofInt(), ofFloat(), ofObject()创建实例外,还都有一个ofPropertyValuesHolder()方法来创建实例,这篇文章我就带大家来看看如何通过ofPropertyValuesHolder()来创建实例的。

由于ValueAnimator和ObjectAnimator都具有ofPropertyValuesHolder()函数,使用方法也差不多,相比而言,ValueAnimator的使用机会不多,这里我们就只讲ObjectAnimator中ofPropertyValuesHolder()的用法。相信大家懂了这篇以后,再去看ValueAnimator的ofPropertyValuesHolder(),也应该是会用的。

一、PropertyValuesHolder
1、概述
PropertyValuesHolder的意义是:它其中保存了动画过程中所需要操作的属性和对应的值。我们通过ofFloat(Object target, String propertyName, float… values)构造的动画,ofFloat()的内部实现其实就是将传进来的参数封装成PropertyValuesHolder实例来保存动画状态。在封装成PropertyValuesHolder实例以后,后期的各种操作也是以PropertyValuesHolder为主。

PropertyValuesHolder中有很多函数,有些函数的api等级是11,有些函数的api等级是14和21; 高api的函数我们就不讲了,只讲讲api 11的函数的用法。

首先,我们来看看创建实例的函数:

public PropertyValuesHolder ofFloat(String propertyName, float... values){}
public PropertyValuesHolder ofInt(String propertyName, int... values){}
public PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object... values){}
public PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values){}

这一段我们着重讲ofFloat、ofInt和ofObject的用法,ofKeyframe我们单独讲。

2、PropertyValuesHolder之ofFloat()、ofInt()
(1)ofFloat()、ofInt():
我们先来看看它们的构造函数:

public static PropertyValuesHolder ofFloat(String propertyName, float... values){}
public static PropertyValuesHolder ofInt(String propertyName, int... values){}

propertyName:表示ObjectAnimator需要操作的属性名。即ObjectAnimator需要通过反射查找对应属性的setProperty()函数的那个property.

values:属性所对应的参数,同样是可变长参数,可以指定多个,还记得我们在ObjectAnimator中讲过,如果只指定了一个,那么ObjectAnimator会通过查找getProperty()方法来获得初始值。

(2)、ObjectAnimator.ofPropertyValuesHolder()

public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values){}

target:指需要执行动画的控件;
values:是一个可变长参数,可以传进去多个PropertyValuesHolder实例,由于每个PropertyValuesHolder实例都会针对一个属性做动画,所以如果传进去多个PropertyValuesHolder实例,将会对控件的多个属性同时做动画操作。

下面我们就举个例子来说明如何通过PropertyValuesHolder的ofFloat、ofInt来做动画。

private void doPropertyAnimator() {PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("Rotation",60f, -60f, 50f, -50f, -40f, 40f, 30f, -30f, 20f, -20f, 10f, -10f, 0f);PropertyValuesHolder holderColor = PropertyValuesHolder.ofInt("BackgroundColor", 0xfffffff0, 0xffff00ff, 0xffffff00, 0xffffff0f);objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mFlAnimator, holder, holderColor);objectAnimator.setDuration(500);objectAnimator.setRepeatMode(ValueAnimator.REVERSE);objectAnimator.setRepeatCount(ValueAnimator.INFINITE);objectAnimator.setInterpolator(new LinearInterpolator());objectAnimator.start();
}

其中,mFlAnimator是自定义TextView(ObjTextView)在xml中的布局,ObjTextView如下:

public class ObjTextView extends TextView {public ObjTextView(Context context, AttributeSet attrs) {super(context, attrs);}public void setCharText(Character character){setText(String.valueOf(character));}
}

Holder对象设定了动画旋转的角度,holderColor对象设定了动画的背景色变化,objectAnimator动画对象里面添加了target控件对象及可变参数Holder和holderColor,当然我们还可以在这里添加别的参数,比如透明度(alpha)的变化,缩放(scale)等动画效果。

3、PropertyValuesHolder之ofObject()
(1)、概述
我们先来看一下ofObject的构造函数:

public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator, Object... values);

参数的含义,再次不多说,不懂的话就找根面条上吊得了。
(2)、示例

public class CharEvaluator implements TypeEvaluator<Character> {@Overridepublic Character evaluate(float v, Character character, Character t1) {int start = (int)character;        int end = (int)t1;char cha = (char)value;return cha;}
}

这段代码简单,前面也已经讲解过很多次了,不多说,不懂的话就找根面条上吊得了。

public class ObjTextView extends TextView {public ObjTextView(Context context, AttributeSet attrs) {super(context, attrs);}public void setCharText(Character character){setText(String.valueOf(character));}
}

从CharEvaluator中可以看出,从CharEvaluator中产出的动画中间值类型为Character类型。TextView中虽然有setText(CharSequence text) 函数,但这个函数的参数类型是CharSequence,而不是Character类型。所以我们要自定义一个类派生自TextView来改变TextView的字符:

public class ObjTextView extends TextView {public ObjTextView(Context context, AttributeSet attrs) {super(context, attrs);}public void setCharText(Character character){setText(String.valueOf(character));}
}

这个与之前上面的相同。

动画的代码如下:

private void doPropertyObjAnimator() {PropertyValuesHolder holderText = PropertyValuesHolder.ofObject("CharText", new CharEvaluator(), new Character('A'), new Character('Z'));PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("Rotation", 60f, -60f, 50f, -50f, -40f, 40f, 30f, -30f, 20f, -20f, 10f, -10f, 0f);PropertyValuesHolder holderColor = PropertyValuesHolder.ofInt("BackgroundColor", 0xfffffff0, 0xffff00ff, 0xffffff00, 0xffffff0f);objectAnimator01 = ObjectAnimator.ofPropertyValuesHolder(mFlAnimator, holderText, holder, holderColor);objectAnimator01.setDuration(2000);objectAnimator01.setInterpolator(new LinearInterpolator());objectAnimator01.setRepeatCount(ValueAnimator.INFINITE);objectAnimator01.setRepeatMode(ValueAnimator.REVERSE);objectAnimator01.start();
}

首先是根据PropertyValuesHolder.ofObject生成一个PropertyValuesHolder实例,注意它的属性就是CharText,所对应的set函数就是setCharText,由于CharEvaluator的中间值是Character类型,所以CharText属性所对应的完整的函数声明为setCharText(Character character);这也就是我们为什么要自定义一个MyTextView原因,就是因为TextView中没有setText(Character character)这样的函数。

二、Keyframe
1、概述:KeyFrame直译过来就是关键帧。 一个关键帧必须包含两个原素,第一时间点,第二位置。即这个关键帧是表示的是某个物体在哪个时间点应该在哪个位置上。

KeyFrame的生成方式为:

Keyframe kf0 = Keyframe.ofFloat(0, 0);
Keyframe kf1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0);

上面生成了三个KeyFrame对象,其中KeyFrame的ofInt函数的声明为:

public static Keyframe ofFloat(float fraction, float value);

fraction:表示当前的显示进度,即从加速器中getInterpolation()函数的返回值;
value:表示当前应该在的位置
比如Keyframe.ofFloat(0, 0)表示动画进度为0时,动画所在的数值位置为0;Keyframe.ofFloat(0.25f, -20f)表示动画进度为25%时,动画所在的数值位置为-20;Keyframe.ofFloat(1f,0)表示动画结束时,动画所在的数值位置为0;

在理解了KeyFrame.ofFloat()的参数以后,我们来看看PropertyValuesHolder是如何使用KeyFrame对象的:

public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values);

fraction:表示当前的显示进度,即从加速器中getInterpolation()函数的返回值;
value:表示当前应该在的位置

PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe(                 "rotation", frame0, frame1, frame2);
mImage, frameHolder);
animator.setDuration(1000);
animator.start();

2、示例:

private void doOfFloatAnim(){Keyframe frame0 = Keyframe.ofFloat(0f, 0);Keyframe frame1= Keyframe.ofFloat(0.1f, -20f);Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);Keyframe frame10 = Keyframe.ofFloat(1, 0);frameHolder = PropertyValuesHolder.ofKeyframe("rotation",  frame0, frame1, frame2, frame3, frame4, frame5, frame6, frame7, frame8, frame9, frame10);frameHolder.setEvaluator(new CharEvaluator());animator = ObjectAnimator.ofPropertyValuesHolder(mIvKeyframe, frameHolder);animator.setDuration(500);animator.setInterpolator(new LinearInterpolator());animator.start();
}

3、Keyframe之ofFloat、ofInt与常用函数

(1)、ofFloat、ofInt
其实Keyframe除了ofFloat()以外,还有ofInt()、ofObject()这些创建Keyframe实例的方法,Keyframe.ofObject()我们下部分再讲,这部分,我们着重看看ofFloat与ofInt的构造函数与使用方法:

public static Keyframe ofFloat(float fraction)
public static Keyframe ofFloat(float fraction, float value)
public static Keyframe ofInt(float fraction)
public static Keyframe ofInt(float fraction, int value)

2)、常用函数:

//设置fraction参数,即Keyframe所对应的进度;
public void setFraction(float fraction)
// 设置当前Keyframe所对应的值;
public void setValue(Object value)
// 设置Keyframe动作期间插值器;
public void setInterpolator(TimeInterpolator interpolator)

这三个函数中,插值器的作用应该是比较难理解,如果给这个Keyframe设置上插值器,那么这个插值器就是从上一个Keyframe开始到当前设置插值器的Keyframe时,这个过程值的计算是利用这个插值器的,比如:

Keyframe frame0 = Keyframe.ofFloat(0f, 0);
Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
frame1.setInterpolator(new BounceInterpolator());
Keyframe frame2 = Keyframe.ofFloat(1f, 20f);
frame2.setInterpolator(new LinearInterpolator());

在上面的代码中,我们给frame1设置了插值器BounceInterpolator,那么在frame0到frame1的中间值计算过程中,就是用的就是回弹插值器;
同样,我们给frame2设置了线性插值器(LinearInterpolator),所以在frame1到frame2的中间值计算过程中,使用的就是线性插值器。很显然,给Keyframe.ofFloat(0f, 0)设置插值器是无效的,因为它是第一帧。

4、Keyframe之ofObject
与ofInt,ofFloat一样,ofObject也有两个构造函数:

public static Keyframe ofObject(float fraction);
public static Keyframe ofObject(float fraction, Object value);

同样,如果使用ofObject(float fraction)来构造,也必须使用setValue(Object value)来设置这个关键帧所对应的值。我们还以TextView更改字母的例子来使用下Keyframe.ofObject.

private void doKeyframeofObject(){Keyframe frame0 = Keyframe.ofObject(0f, new Character('A'));Keyframe frame1 = Keyframe.ofObject(0.1f, new Character('L'));Keyframe frame2 = Keyframe.ofObject(1,new Character('Z'));frameHolder02 = PropertyValuesHolder.ofKeyframe("CharText",frame0,frame1,frame2);frameHolder02.setEvaluator(new CharEvaluator());animator02 = ObjectAnimator.ofPropertyValuesHolder(mFlAnimator, frameHolder);animator02.setDuration(3000);animator02.start();
}

利用关键帧创建PropertyValuesHolder后,一定要记得设置自定义的Evaluator:

frameHolder02.setEvaluator(new CharEvaluator());

凡是使用ofObject来做动画的时候,都必须调用frameHolder.setEvaluator显示设置Evaluator,因为系统根本是无法知道,你动画的中间值Object真正是什么类型的。
如果去掉第0帧,将以第一个关键帧为起始位置
如果去掉结束帧,将以最后一个关键帧为结束位置
使用Keyframe来构建动画,至少要有两个或两个以上帧

三、PropertyValuesHolder的其它函数

 // 设置动画的Evaluator public void setEvaluator(TypeEvaluator evaluator);// 用于设置ofFloat所对应的动画值列表 public void setFloatValues(float... values);// 用于设置ofInt所对应的动画值列表 public void setIntValues(int... values);// 用于设置ofKeyframe所对应的动画值列表 public void setKeyframes(Keyframe... values);// 用于设置ofObject所对应的动画值列表 public void setObjectValues(Object... values);// 设置动画属性名 public void setPropertyName(String propertyName);

这些函数都比较好理解。
如果是利用PropertyValuesHolder.ofObject()来创建动画实例的话,我们是一定要显示调用 PropertyValuesHolder.setEvaluator()来设置Evaluator的。谨记!谨记!!谨记!!!

动画七、动画的PropertyValuesHolder与Keyframe相关推荐

  1. 自定义控件三部曲之动画篇(八)——PropertyValuesHolder与Keyframe

    前言:只有比牛人跑的更快,才有可能追上他的脚步. 相关文章: <Android自定义控件三部曲文章索引>:http://blog.csdn.net/harvic880925/article ...

  2. android+桌面文件夹动画,Android动画

    1.为什么要说动画? 动画的适用是Android开发常用的知识 种类繁多,适用复杂,很多实现需要自定义动画 2.目前Android中有多少种动画? 视图动画(View 动画) 属性动画 揭露动画(Re ...

  3. 【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )

    文章目录 ◯.AnimatedBuilder 引入 一.创建动画控制器 二.创建动画 三.创建动画作用的组件 四.创建 AnimatedBuilder 关联动画与组件 五.动画运行 六.完整代码示例 ...

  4. 【Flutter】Animation 动画 ( Flutter 动画基本流程 | 创建动画控制器 | 创建动画 | 设置值监听器 | 设置状态监听器 | 布局中使用动画值 | 动画运行 )

    文章目录 一.创建动画控制器 二.创建动画 三.设置值监听器 四.设置状态监听器 五.布局中使用动画值 六.动画运行 七.完整代码示例 八.相关资源 Flutter 动画基本流程 : ① 创建动画控制 ...

  5. android的md动画,Android-notes/动画体系详解.md at master · drs0214/Android-notes · GitHub

    Android 动画详解:属性动画.View 动画和帧动画 在 Android 中,基本的动画共有三种类型: View 动画:也叫视图动画或者补间动画,主要是指 android.view.animat ...

  6. swiftui动画之tab自定义切换动画_Unity动画系统详解1:在Unity中如何制作动画?

    摘要:在场景中加入动态的物体,可以让整个场景更加生动.真实.Unity场景中的物体可以通过制作动画,让物体动起来.简单的动画如物体的移动.旋转(比如旋转的风扇.闪烁不定的灯泡等),复杂的动画如游戏中角 ...

  7. 不会做动画的程序猿不是好的动画师(如何用css3动画做动画)

    "看清animation,transform, @keyframes,transition这四个的脸,以后这四个来了就是要做动画了,看好你们的网页,除了这四个,谁管你们都不好使." ...

  8. 属性动画Android动画,Android动画(三)属性动画Animator与Interpolator

    概述 继上一篇,Android中的视图动画和帧动画可以实现大部分的Android中的动画需求,但是有一个缺点,就是其事件响应区域并没有发生变化,这时候出现了属性动画完全弥补了这个缺点 属性动画结构 可 ...

  9. android动画机制,动画机制-《Android群英传》

    动画分为视图动画和属性动画框架. 视图动画: 提供AlphaAnimation.RotateAnimation.TranslateAnimation.ScaleAnimation四种动画方式 提供动画 ...

最新文章

  1. 修改项目名称后,部署到tomcat问题
  2. XXX管理平台系统——架构
  3. ViewState提交后丢失,竟然是OnInit搞的鬼
  4. 系统性能提升利刃 | 缓存技术使用的实践与思考
  5. Android脚本打包
  6. 如何成为更优秀的工程师?
  7. python中try怎么用_python下try
  8. 蓝桥杯 ALGO-115 算法训练 和为T
  9. Qt Supported Databases
  10. 用TensorFlow训练一个目标检测器(手把手教学版)
  11. Python3异常-AttributeError: module 'sys' has no attribute 'setdefaultencoding'
  12. 数学:深入浅出通信原理(陈爱军)
  13. 目标规划运筹学例题doc_第八章 运筹学 目标规划 案例.doc
  14. 码云上传文件夹_本地上传码云文件
  15. android手机浏览器测评,九款手机浏览器评测总结
  16. 哗啦啦收银系统故障收集
  17. 微信红包数字变化动态图片_微信红包数字动图下载_微信动态图片红包图下载_游戏吧...
  18. Linux下压缩/解压缩的命令
  19. Java freemarker 生成word文档
  20. 使用 Microsoft RDC for Mac 在 Mac 和 Windows 间传文件

热门文章

  1. 通过pdf的url在线浏览pdf
  2. maya2018自带模型的打开
  3. 西米推荐-FileYee:可能是最简单安全的数据文件备份软件
  4. 数学建模算法(1)—规划模型及其python实现
  5. win10资源管理器打开一直正在处理文件加载不出来,桌面图标不加载
  6. 通过javascript获取sharepoint数据,使用JS导出Excel
  7. Excel VBA 操作键盘(如:移动方向键,上下左右等)
  8. 前后端传图片用base64好吗_Base64是什么?前端用Base64加载图片到底好不好?
  9. MacBook Pro (M1 Pro芯片)使用安卓USB共享上网
  10. 怎么找到当地供应商_微商怎么找一手货源供货商(微商新手必看教程)