objectanimator.ofint duration是怎么调整速度的

ObjectAnimator是ValueAnimator的子类,他本身就已经包含了时间引擎和值计算,所以它拥有为对象的某个属性设置动画的功能。这使得为任何对象设置动画更加的容易。你不再需要实现 ValueAnimator.AnimatorUpdateListener接口,因为ObjectAnimator动画自己会自动更新相应的属性值。
ObjectAnimator的实例和ValueAnimator是类似的,但是你需要描叙该对象,需要设置动画的属性的名字(一个字符串),以及动画属性值的变化范围:
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, &alpha&, 0f, 1f);
anim.setDuration(1000);
anim.start();
为了使ObjectAnimator正确的更新属性值,你需要:
1、你要设置动画的对象的属性必须有一个set该值的方法。因为ObjectAnimator在动画的过程中自动更新属性值,这是通过调用该属性的set方法来实现的。例如,如果属性的名字是foo,你需要有一个setFoo()的方法,如果不存在set方法,你可以有下面三个选择:
1)、如果你有权限,你可以为该类添加一个set方法;
2)、使用一个包裹类,通过该包裹类你可以去修改和获取属性值的变化,然后把它向前定向到原来的值
3)、使用ValueAnimator类替换
2、如果你在一个ObjectAnimator中只为属性值设置一个值,这个值被任务是动画的结束值。 这样的话,该对象必须有一个get方法来获取该属性值作为动画的起始值.get方法必须类似于get&属性名&.例如,如果属性的名字叫foo,你需要有一个getFoo(),方法。
3、动画的属性值的gettter()方法(如果需要)和setter方法必须作用跟ObjectAnimator中的起始值是一个类型,例如如果你构造ObjectAnimator的方式是如下这样的,则该属性值的getter和setter方法必须如targetObject.setPropName(float) 和targetObject.getPropName(float),即都是浮点型
ObjectAnimator.ofFloat(targetObject, &propName&, 1f)
4、依赖于你设置动画的对象和属性,你可能需要调用View的invalidate来强制屏幕重现绘制以及更新动画值。你可以在 onAnimationUpdate()中做这个工作。例如,为一个Drawable对象的颜色属性设置动画,你仅仅需要在该对象重绘的时候更新屏幕。所有View属性的set方法,例如setAlpha()和setTranslationX()自己会调用invalid方法,所以当这些属性值有更新时,你不需要再次调用invalid方法。要获取更多关于监听器的信息。你可以查看监听器章节。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:361次
排名:千里之外
转载:17篇
(4)(11)(2)(1)ObjectAnimator是ValueAnimator的子类,他本身就已经包含了时间引擎和值计算,所以它拥有为对象的某个属性设置动画的功能。这使得为任何对象设置动画更加的容易。你不再需要实现 ValueAnimator.AnimatorUpdateListener接口,因为ObjectAnimator动画自己会自动更新相应的属性值。ObjectAnimator的实例和ValueAnimator是类似的,但是你需要描叙该对象,需要设置动画的属性的名字(一个字符串),以及动画属性值的变化范围:ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);anim.setDuration(1000);anim.start();为了使ObjectAnimator正确的更新属性值,你需要:1、你要设置动画的对象的属性必须有一个set该值的方法。因为ObjectAnimator在动画的过程中自动更新属性值,这是通过调用该属性的set方法来实现的。例如,如果属性的名字是foo,你需要有一个setFoo()的方法,如果不存在set方法,你可以有下面三个选择:1)、如果你有权限,你可以为该类添加一个set方法;2)、使用一个包裹类,通过该包裹类你可以去修改和获取属性值的变化,然后把它向前定向到原来的值3)、使用ValueAnimator类替换2、如果你在一个ObjectAnimator中只为属性值设置一个值,这个值被任务是动画的结束值。 这样的话,该对象必须有一个get方法来获取该属性值作为动画的起始值.get方法必须类似于get&属性名&.例如,如果属性的名字叫foo,你需要有一个getFoo(),方法。3、动画的属性值的gettter()方法(如果需要)和setter方法必须作用跟ObjectAnimator中的起始值是一个类型,例如如果你构造ObjectAnimator的方式是如下这样的,则该属性值的getter和setter方法必须如targetObject.setPropName(float) 和targetObject.getPropName(float),即都是浮点型ObjectAnimator.ofFloat(targetObject, "propName", 1f)4、依赖于你设置动画的对象和属性,你可能需要调用View的invalidate来强制屏幕重现绘制以及更新动画值。你可以在 onAnimationUpdate()中做这个工作。例如,为一个Drawable对象的颜色属性设置动画,你仅仅需要在该对象重绘的时候更新屏幕。所有View属性的set方法,例如setAlpha()和setTranslationX()自己会调用invalid方法,所以当这些属性值有更新时,你不需要再次调用invalid方法。要获取更多关于监听器的信息。你可以查看监听器章节。
阅读(...) 评论()50218人阅读
Android疑难解析(41)
转载请注明出处:大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了。但是,正如上篇文章当中所说到的,属性动画对补间动画进行了很大幅度的改进,之前补间动画可以做到的属性动画也能做到,补间动画做不到的现在属性动画也可以做到了。因此,今天我们就来学习一下属性动画的高级用法,看看如何实现一些补间动画所无法实现的功能。阅读本篇文章需要你对属性动画有一定的了解,并且掌握属性动画的基本用法,如果你还对属性动画不够了解的话,建议先去阅读 &。ValueAnimator的高级用法在上篇文章中介绍补间动画缺点的时候有提到过,补间动画是只能对View对象进行动画操作的。而属性动画就不再受这个限制,它可以对任意对象进行动画操作。那么大家应该还记得在上篇文章当中我举的一个例子,比如说我们有一个自定义的View,在这个View当中有一个Point对象用于管理坐标,然后在onDraw()方法当中就是根据这个Point对象的坐标值来进行绘制的。也就是说,如果我们可以对Point对象进行动画操作,那么整个自定义View的动画效果就有了。OK,下面我们就来学习一下如何实现这样的效果。在开始动手之前,我们还需要掌握另外一个知识点,就是TypeEvaluator的用法。可能在大多数情况下我们使用属性动画的时候都不会用到TypeEvaluator,但是大家还是应该了解一下它的用法,以防止当我们遇到一些解决不掉的问题时能够想起来还有这样的一种解决方案。那么TypeEvaluator的作用到底是什么呢?简单来说,就是告诉动画系统如何从初始值过度到结束值。我们在上一篇文章中学到的ValueAnimator.ofFloat()方法就是实现了初始值与结束值之间的平滑过度,那么这个平滑过度是怎么做到的呢?其实就是系统内置了一个FloatEvaluator,它通过计算告知动画系统如何从初始值过度到结束值,我们来看一下FloatEvaluator的代码实现:public class FloatEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
}可以看到,FloatEvaluator实现了TypeEvaluator接口,然后重写evaluate()方法。evaluate()方法当中传入了三个参数,第一个参数fraction非常重要,这个参数用于表示动画的完成度的,我们应该根据它来计算当前动画的值应该是多少,第二第三个参数分别表示动画的初始值和结束值。那么上述代码的逻辑就比较清晰了,用结束值减去初始值,算出它们之间的差值,然后乘以fraction这个系数,再加上初始值,那么就得到当前动画的值了。好的,那FloatEvaluator是系统内置好的功能,并不需要我们自己去编写,但介绍它的实现方法是要为我们后面的功能铺路的。前面我们使用过了ValueAnimator的ofFloat()和ofInt()方法,分别用于对浮点型和整型的数据进行动画操作的,但实际上ValueAnimator中还有一个ofObject()方法,是用于对任意对象进行动画操作的。但是相比于浮点型或整型数据,对象的动画操作明显要更复杂一些,因为系统将完全无法知道如何从初始对象过度到结束对象,因此这个时候我们就需要实现一个自己的TypeEvaluator来告知系统如何进行过度。下面来先定义一个Point类,如下所示:public class Point {
public Point(float x, float y) {
public float getX() {
public float getY() {
}Point类非常简单,只有x和y两个变量用于记录坐标的位置,并提供了构造方法来设置坐标,以及get方法来获取坐标。接下来定义PointEvaluator,如下所示:public class PointEvaluator implements TypeEvaluator{
public Object evaluate(float fraction, Object startValue, Object endValue) {
Point startPoint = (Point) startV
Point endPoint = (Point) endV
float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());
Point point = new Point(x, y);
}可以看到,PointEvaluator同样实现了TypeEvaluator接口并重写了evaluate()方法。其实evaluate()方法中的逻辑还是非常简单的,先是将startValue和endValue强转成Point对象,然后同样根据fraction来计算当前动画的x和y的值,最后组装到一个新的Point对象当中并返回。这样我们就将PointEvaluator编写完成了,接下来我们就可以非常轻松地对Point对象进行动画操作了,比如说我们有两个Point对象,现在需要将Point1通过动画平滑过度到Point2,就可以这样写:Point point1 = new Point(0, 0);
Point point2 = new Point(300, 300);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), point1, point2);
anim.setDuration(5000);
anim.start();代码很简单,这里我们先是new出了两个Point对象,并在构造函数中分别设置了它们的坐标点。然后调用ValueAnimator的ofObject()方法来构建ValueAnimator的实例,这里需要注意的是,ofObject()方法要求多传入一个TypeEvaluator参数,这里我们只需要传入刚才定义好的PointEvaluator的实例就可以了。好的,这就是自定义TypeEvaluator的全部用法,掌握了这些知识之后,我们就可以来尝试一下如何通过对Point对象进行动画操作,从而实现整个自定义View的动画效果。新建一个MyAnimView继承自View,代码如下所示:public class MyAnimView extends View {
public static final float RADIUS = 50f;
private Point currentP
private Paint mP
public MyAnimView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
protected void onDraw(Canvas canvas) {
if (currentPoint == null) {
currentPoint = new Point(RADIUS, RADIUS);
drawCircle(canvas);
startAnimation();
drawCircle(canvas);
private void drawCircle(Canvas canvas) {
float x = currentPoint.getX();
float y = currentPoint.getY();
canvas.drawCircle(x, y, RADIUS, mPaint);
private void startAnimation() {
Point startPoint = new Point(RADIUS, RADIUS);
Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
currentPoint = (Point) animation.getAnimatedValue();
invalidate();
anim.setDuration(5000);
anim.start();
}基本上还是很简单的,总共也没几行代码。首先在自定义View的构造方法当中初始化了一个Paint对象作为画笔,并将画笔颜色设置为蓝色,接着在onDraw()方法当中进行绘制。这里我们绘制的逻辑是由currentPoint这个对象控制的,如果currentPoint对象不等于空,那么就调用drawCircle()方法在currentPoint的坐标位置画出一个半径为50的圆,如果currentPoint对象是空,那么就调用startAnimation()方法来启动动画。那么我们来观察一下startAnimation()方法中的代码,其实大家应该很熟悉了,就是对Point对象进行了一个动画操作而已。这里我们定义了一个startPoint和一个endPoint,坐标分别是View的左上角和右下角,并将动画的时长设为5秒。然后有一点需要大家注意的,就是我们通过监听器对动画的过程进行了监听,每当Point值有改变的时候都会回调onAnimationUpdate()方法。在这个方法当中,我们对currentPoint对象进行了重新赋值,并调用了invalidate()方法,这样的话onDraw()方法就会重新调用,并且由于currentPoint对象的坐标已经改变了,那么绘制的位置也会改变,于是一个平移的动画效果也就实现了。下面我们只需要在布局文件当中引入这个自定义控件:&RelativeLayout xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
&com.example.tony.myapplication.MyAnimView
android:layout_width=&match_parent&
android:layout_height=&match_parent& /&
&/RelativeLayout&最后运行一下程序,效果如下图所示:OK!这样我们就成功实现了通过对对象进行值操作来实现动画效果的功能,这就是ValueAnimator的高级用法。ObjectAnimator的高级用法ObjectAnimator的基本用法和工作原理在上一篇文章当中都已经讲解过了,相信大家都已经掌握。那么大家应该都还记得,我们在吐槽补间动画的时候有提到过,补间动画是只能实现移动、缩放、旋转和淡入淡出这四种动画操作的,功能限定死就是这些,基本上没有任何扩展性可言。比如我们想要实现对View的颜色进行动态改变,补间动画是没有办法做到的。但是属性动画就不会受这些条条框框的限制,它的扩展性非常强,对于动态改变View的颜色这种功能是完全可是胜任的,那么下面我们就来学习一下如何实现这样的效果。大家应该都还记得,ObjectAnimator内部的工作机制是通过寻找特定属性的get和set方法,然后通过方法不断地对值进行改变,从而实现动画效果的。因此我们就需要在MyAnimView中定义一个color属性,并提供它的get和set方法。这里我们可以将color属性设置为字符串类型,使用#RRGGBB这种格式来表示颜色值,代码如下所示:public class MyAnimView extends View {
public String getColor() {
public void setColor(String color) {
this.color =
mPaint.setColor(Color.parseColor(color));
invalidate();
}注意在setColor()方法当中,我们编写了一个非常简单的逻辑,就是将画笔的颜色设置成方法参数传入的颜色,然后调用了invalidate()方法。这段代码虽然只有三行,但是却执行了一个非常核心的功能,就是在改变了画笔颜色之后立即刷新视图,然后onDraw()方法就会调用。在onDraw()方法当中会根据当前画笔的颜色来进行绘制,这样颜色也就会动态进行改变了。那么接下来的问题就是怎样让setColor()方法得到调用了,毫无疑问,当然是要借助ObjectAnimator类,但是在使用ObjectAnimator之前我们还要完成一个非常重要的工作,就是编写一个用于告知系统如何进行颜色过度的TypeEvaluator。创建ColorEvaluator并实现TypeEvaluator接口,代码如下所示:public class ColorEvaluator implements TypeEvaluator {
private int mCurrentRed = -1;
private int mCurrentGreen = -1;
private int mCurrentBlue = -1;
public Object evaluate(float fraction, Object startValue, Object endValue) {
String startColor = (String) startV
String endColor = (String) endV
int startRed = Integer.parseInt(startColor.substring(1, 3), 16);
int startGreen = Integer.parseInt(startColor.substring(3, 5), 16);
int startBlue = Integer.parseInt(startColor.substring(5, 7), 16);
int endRed = Integer.parseInt(endColor.substring(1, 3), 16);
int endGreen = Integer.parseInt(endColor.substring(3, 5), 16);
int endBlue = Integer.parseInt(endColor.substring(5, 7), 16);
// 初始化颜色的值
if (mCurrentRed == -1) {
mCurrentRed = startR
if (mCurrentGreen == -1) {
mCurrentGreen = startG
if (mCurrentBlue == -1) {
mCurrentBlue = startB
// 计算初始颜色和结束颜色之间的差值
int redDiff = Math.abs(startRed - endRed);
int greenDiff = Math.abs(startGreen - endGreen);
int blueDiff = Math.abs(startBlue - endBlue);
int colorDiff = redDiff + greenDiff + blueD
if (mCurrentRed != endRed) {
mCurrentRed = getCurrentColor(startRed, endRed, colorDiff, 0,
fraction);
} else if (mCurrentGreen != endGreen) {
mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff,
redDiff, fraction);
} else if (mCurrentBlue != endBlue) {
mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff,
redDiff + greenDiff, fraction);
// 将计算出的当前颜色的值组装返回
String currentColor = &#& + getHexString(mCurrentRed)
+ getHexString(mCurrentGreen) + getHexString(mCurrentBlue);
return currentC
* 根据fraction值来计算当前的颜色。
private int getCurrentColor(int startColor, int endColor, int colorDiff,
int offset, float fraction) {
int currentC
if (startColor & endColor) {
currentColor = (int) (startColor - (fraction * colorDiff - offset));
if (currentColor & endColor) {
currentColor = endC
currentColor = (int) (startColor + (fraction * colorDiff - offset));
if (currentColor & endColor) {
currentColor = endC
return currentC
* 将10进制颜色值转换成16进制。
private String getHexString(int value) {
String hexString = Integer.toHexString(value);
if (hexString.length() == 1) {
hexString = &0& + hexS
return hexS
}这大概是我们整个动画操作当中最复杂的一个类了。没错,属性动画的高级用法中最有技术含量的也就是如何编写出一个合适的TypeEvaluator。好在刚才我们已经编写了一个PointEvaluator,对它的基本工作原理已经有了了解,那么这里我们主要学习一下ColorEvaluator的逻辑流程吧。首先在evaluate()方法当中获取到颜色的初始值和结束值,并通过字符串截取的方式将颜色分为RGB三个部分,并将RGB的值转换成十进制数字,那么每个颜色的取值范围就是0-255。接下来计算一下初始颜色值到结束颜色值之间的差值,这个差值很重要,决定着颜色变化的快慢,如果初始颜色值和结束颜色值很相近,那么颜色变化就会比较缓慢,而如果颜色值相差很大,比如说从黑到白,那么就要经历255*3这个幅度的颜色过度,变化就会非常快。那么控制颜色变化的速度是通过getCurrentColor()这个方法来实现的,这个方法会根据当前的fraction值来计算目前应该过度到什么颜色,并且这里会根据初始和结束的颜色差值来控制变化速度,最终将计算出的颜色进行返回。最后,由于我们计算出的颜色是十进制数字,这里还需要调用一下getHexString()方法把它们转换成十六进制字符串,再将RGB颜色拼装起来之后作为最终的结果返回。好了,ColorEvaluator写完之后我们就把最复杂的工作完成了,剩下的就是一些简单调用的问题了,比如说我们想要实现从蓝色到红色的动画过度,历时5秒,就可以这样写:ObjectAnimator anim = ObjectAnimator.ofObject(myAnimView, &color&, new ColorEvaluator(),
&#0000FF&, &#FF0000&);
anim.setDuration(5000);
anim.start();用法非常简单易懂,相信不需要我再进行解释了。接下来我们需要将上面一段代码移到MyAnimView类当中,让它和刚才的Point移动动画可以结合到一起播放,这就要借助我们在上篇文章当中学到的组合动画的技术了。修改MyAnimView中的代码,如下所示:public class MyAnimView extends View {
private void startAnimation() {
Point startPoint = new Point(RADIUS, RADIUS);
Point endPoint = new Point(getWidth() - RADIUS, getHeight() - RADIUS);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
currentPoint = (Point) animation.getAnimatedValue();
invalidate();
ObjectAnimator anim2 = ObjectAnimator.ofObject(this, &color&, new ColorEvaluator(),
&#0000FF&, &#FF0000&);
AnimatorSet animSet = new AnimatorSet();
animSet.play(anim).with(anim2);
animSet.setDuration(5000);
animSet.start();
}可以看到,我们并没有改动太多的代码,重点只是修改了startAnimation()方法中的部分内容。这里先是将颜色过度的代码逻辑移动到了startAnimation()方法当中,注意由于这段代码本身就是在MyAnimView当中执行的,因此ObjectAnimator.ofObject()的第一个参数直接传this就可以了。接着我们又创建了一个AnimatorSet,并把两个动画设置成同时播放,动画时长为五秒,最后启动动画。现在重新运行一下代码,效果如下图所示:OK,位置动画和颜色动画非常融洽的结合到一起了,看上去效果还是相当不错的,这样我们就把ObjectAnimator的高级用法也掌握了。好的,通过本篇文章的学习,我们对属性动画已经有了颇为深刻的认识,那么本篇文章的内容到此为止,下篇文章当中将会介绍更多关于属性动画的其它技巧,感兴趣的朋友请继续阅读 &。第一时间获得博客更新提醒,以及更多技术信息分享,欢迎关注我的微信公众号,扫一扫下方二维码或搜索微信号guolin_blog,即可关注。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4856612次
积分:34091
积分:34091
排名:第98名
原创:89篇
评论:10852条
如果喜欢我写的博客也许你会更加喜欢我写的书书中拥有更多全新Android知识和博客并无交集
网上购买:
书中源码下载:
书中章节试读:
关注我的微信公众号,每天都有优质技术文章推送,你还可以向公众号投稿,将自己总结的技术心得分享给大家。扫一扫下方二维码或在微信搜索 郭霖 即可关注:
感兴趣的朋友可以加入我的QQ群,一起讨论学习,共同进步。
阅读:338551
(1)(1)(2)(1)(1)(2)(1)(1)(2)(1)(1)(1)(1)(1)(1)(1)(2)(2)(3)(1)(2)(5)(3)(3)(2)(1)(3)(1)(2)(5)(4)(4)(4)(4)(5)(5)(5)(6)(4)属性动画与补间动画最大的区别就是,控件通过属性动画改变位置后,控件的位置会随着改变,而补间动画控件还是在原地。
Duration:动画持续时间,默认持续时间为300ms
Time Interpolation:时间差值,与补间动画的Interpolation相似,即改变动画执行速度
Repeat count and behavior:重复次数及模式
Animator sets:动画集合
Frame refresh delay:多久刷新一次帧,默认10ms,依赖系统执行的状态
ObjectAnimator:动画的执行类
ValueAnimator:动画的执行类
AnimatorSet:动画集合
AnmatorInflater:加载文件夹为animator的xml文件
TypeEvaluator:类型估值,主要用于设置动画操作属性的值
TimeInterpolator:时间差值
以下是代码的应用:
package com.example.
import android.os.B
import android.animation.A
import android.animation.Animator.AnimatorL
import android.animation.AnimatorI
import android.animation.AnimatorListenerA
import android.animation.AnimatorS
import android.animation.IntE
import android.animation.ObjectA
import android.animation.PropertyValuesH
import android.animation.TypeE
import android.animation.ValueA
import android.animation.ValueAnimator.AnimatorUpdateL
import android.annotation.SuppressL
import android.app.A
import android.graphics.PointF;
import android.view.V
import android.view.ViewGroup.LayoutP
@SuppressLint(&NewApi&)
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
* xml绑定标签
* @param v
* x方向上旋转的动画效果
public void a(View v) {
//属性动画的动画执行类
* @parm target--&要操作的属性的对象(如果为T类型则是泛型,Object所有类型)
* @parm property--&要操作的属性的名称,即v对象的set方法中的属性都可以改变
* @parm values--&改变该属性的值
ObjectAnimator animator = ObjectAnimator.ofFloat(v, &rotationX&, 0,360.0f,0);//从0--&360--&0
animator.setDuration(3000);//执行时间
animator.start();//启动动画
* 同时设置多个属性的动画效果
* 透明度从0到1,拉伸从0到1再拉伸到2倍(变化的趋势一样)
public void b(final View v) {
ObjectAnimator animator = ObjectAnimator.ofFloat(v, &&, 0,1);
animator.setDuration(5000);
animator.start();
//添加在更新时的监听事件
animator.addUpdateListener(new AnimatorUpdateListener() {
//每次动画刷新的时候就会执行该方法
public void onAnimationUpdate(ValueAnimator arg0) {
//此次刷新时改变的值
float value = (Float) arg0.getAnimatedValue();
v.setAlpha(value);
float scaleX = 2 *//拉伸到2倍
v.setScaleX(scaleX);
v.setScaleY(scaleX);
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat(&scaleX&, 0,2);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat(&scaleY&, 0,2);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat(&alpha&, 0,1);
//同时在v上设置三个动画效果,参数2为可变参数
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(v, holder1,holder2,holder3);
animator.setDuration(5000);
animator.start();
* 设置控件的宽高
public void c(final View v) {
button.setWidth(pixels)//不是设置控件宽度,是设置控件的最大宽度
ObjectAnimator animator = ObjectAnimator.ofFloat(v, &&, 0, 200);
animator.setDuration(4000);
animator.start();
//若改变的属性没有set方法,可以在监听事件中进行修改
animator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator arg0) {
float value = (Float) arg0.getAnimatedValue();
* 改变控件的宽高
//获取布局参数
LayoutParams params = v.getLayoutParams();//统一的父类ViewGroup,所以不用强转
params.width = (int)
params.height = (int)
v.requestLayout();//请求布局,刷新布局参数,一般使用这个。只要布局改变了调用这个方法都有效果
v.setLayoutParams(params);
* 使用类型估值(TypeValue)设置控件的宽高
public void d(final View v) {
final int width = v.getWidth();
ObjectAnimator animator = ObjectAnimator.ofFloat(v, &&, 1, 100);
animator.setDuration(4000);
animator.start();
//若改变的属性没有set方法,可以在监听事件中进行修改
animator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator arg0) {
float value = (Float) arg0.getAnimatedValue();//获取每次改变的值
FloatEvaluator
IntEvaluator intEvaluator = new IntEvaluator();//获取类型估值对象
* 改变控件的宽高
//获取布局参数
LayoutParams params = v.getLayoutParams();//统一的父类ViewGroup,所以不用强转
//每次改变的值为:(200-width)/100
params.width = (int) (width + value*(200-width)/100);//目的:每次变化的值都一样,不管控件的大小是多少
//参数1每次改变的值(每次改变的比例),参数2为起始的值,参数3为结束的值
//参数1已经写好了:(结束的值-起始的值)*value
params.width = intEvaluator.evaluate(value/100, width, 200);
params.height = (int)
v.requestLayout();
* 类型估值的应用
public void e(final View v) {
//让控件随着设置的点移动,PointF浮点数坐标
TypeEvaluator&PointF& evaluator = new TypeEvaluator&PointF&() {
* 估算每次移动时的位置
* @param arg0 --&此次变化的比例
* @param arg1 --&最开始的时候的位置
* @param arg2 --&最后的位置
public PointF evaluate(float arg0, PointF arg1, PointF arg2) {
PointF pointF = new PointF();
pointF.x = (arg2.x-arg1.x)*arg0+arg1.x;
pointF.y = (arg2.y-arg1.y)*arg0+arg1.y;
return pointF;
PointF start = new PointF(v.getLeft(), v.getTop());//起始的位置
PointF end = new PointF(200, 200);//结束的位置
ObjectAnimator objectAnimator = ObjectAnimator.ofObject(v, &&, evaluator, start,end);
objectAnimator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator arg0) {
PointF pointF = (PointF) arg0.getAnimatedValue();
v.setX(pointF.x);
v.setY(pointF.y);
objectAnimator.setDuration(1000);
objectAnimator.start();
* ValueAnimtor
public void f(final View v) {
ValueAnimator animator = new ValueAnimator();
//设置动画变化的值
animator.setFloatValues(0,360,0);
animator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
v.setRotationX(value);
animator.setDuration(1000);
animator.start();
* 监听动画状态
public void g(View v) {
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.cancel();//取消动画
* 状态变化时就会执行
valueAnimator.addListener(new AnimatorListener() {
//开始动画的状态
public void onAnimationStart(Animator animation) {
//重复的状态
public void onAnimationRepeat(Animator animation) {
//动画结束的时候
public void onAnimationEnd(Animator animation) {
//动画取消的状态,即调用cancel()方法时才会调用
public void onAnimationCancel(Animator animation) {
* 监听动画的状态
* 添加AnimatorListenerAdapter监听事件,按照需要重写需要监听的动画状态的方法
//AnimatorListenerAdapter抽象类,方法都已经重写,但是方法体都是空的
valueAnimator.addListener(new AnimatorListenerAdapter() {
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
* AnimatorSet
* 动画的集合
public void h() {
ValueAnimator v1 = new ValueAnimator();
ValueAnimator v2 = new ValueAnimator();
ValueAnimator v3 = new ValueAnimator();
AnimatorSet animatorSet = new AnimatorSet();
//播放v1和v2一起
animatorSet.play(v1).with(v2);
//播放v3在v2之后
animatorSet.play(v3).after(v2);
//全部一起播放
animatorSet.playTogether(v1,v2,v3);
//按顺序播放,写前面的先播放
animatorSet.playSequentially(v1,v2,v3);
//每一个动画执行的时间
animatorSet.setDuration(1000);
animatorSet.start();
* xml中设置属性动画
public void i(View v) {
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.object);
//设置操作的控件
animator.setTarget(v);
animator.start();
xml文件如下:
值得注意的是属性动画的res下的文件夹应该是animator
&?xml version=&1.0& encoding=&utf-8&?&
&!--propertyName:属性
&!--valueType:变化值的类型
&objectAnimator xmlns:android=&/apk/res/android&
android:valueType=&floatType&
android:valueFrom=&0&
android:valueTo=&360&
android:propertyName=&rotationX&&
&/objectAnimator&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:934次
排名:千里之外
原创:24篇}

我要回帖

更多关于 objectanimator 旋转 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信