Component 是一个强大的、完善的组件化框架. 欢迎大家使用
请尊重别人劳动成果转载请注明出处:http://blog.csdn.net/u011692041/article/details/51471743
前言 The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property's (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object's position on the screen, how long you want to animate it for, and what values you want to animate between
最主要的区别就是属性动画是通过改变对象的属性来改变对象在屏幕中的展示效果,而基本动画则不是
所以我们如果需要View动画之后就停在动画后的位置,有的人说基本动画通过设置也是可以做到的(那只是一个假象,通过测试你可以很容易的测试出来,比如点击事件还是在原来的位置发生的,第二个动画开启之后,又是从原来的地方开始动画的等等).所以如果你想做到View动画以后是真的如效果一样属性也跟着改变了,这时候你就非得用属性动画不可,这也是属性动画出现的一个重要的原因.掰扯了这么多,带大伙走一个呗!
这段话来自Android官网的属性动画的开头部分,大概解释了一下属性动画,为了读者的阅读方便,这里对它进行一个简单的翻译
属性动画是一个健壮的框架,它允许你去让任何Android中的对象动起来.你可以定义一个动画去改变任何对象的属性,不管这个对象是不是被绘制到屏幕上.一个属性动画在一段时间内改变一个属性的值(其实就是我们平常写的对象中的一个字段,你也可以理解成对象中的成员变量).有些情况下,你指定了你想去改变的对象属性,比如一个对象在屏幕中的位置、你想要动画持续的时长和在动画的期间对象的属性值.
翻译的不是很好,但是我们大致已经可以看出属性动画不同于平常我们所接触的那些基本动画View Animation:渐变动画和帧动画
ObjectAnimator
xml文件,就是一张逗比图
Activity代码
public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} public void animation(final View v) {ObjectAnimator//
.ofFloat(v, "rotation", 0, 90)//
.setDuration(2000)//
.start();
}}
代码很简单,先看效果再给解释
文章图片
ObjectAnimator对象的方法详解
ofInt(Object target, String propertyName, int... values)
ofFloat(Object target, String propertyName, float... values)
ofObject(Object target, String propertyName,
TypeEvaluator evaluator, Object... values)
这里以ofInt和ofFloat方法为例,ofObject方法中多了一个参数,下面单独解释
第一个参数就是动画作用的对象,注意这里是Object类型哦,这也印证了最上面陈述的,动画可以作用于任何的对象
第二个参数是属性的名字,也就是target对象中的属性(需要有set方法),内部使用了反射进行调用该属性的set方法
第三个参数是属性的值,可以看到是一个可变数组,根据数组的长度,分为以下几种情况
长度为1:开始的值为对象中该属性的当前值(通过反射调用get方法获取),结束的值为传入的值
长度为2:开始值为传入的第一个值,结束值为传入的第二个值
在ofObject方法中多了一个参数,类型为TypeEvaluator,是一个接口
public interface TypeEvaluator {/**
* This function returns the result of linearly interpolating the start and end values, with
* fraction
representing the proportion between the start and end values. The
* calculation is a simple parametric calculation: result = x0 + t * (v1 - v0)
,
* where x0
is startValue
, x1
is endValue
,
* and t
is fraction
.
*
* @param fractionThe fraction from the starting to the ending values
* @param startValue The start value.
* @param endValueThe end value.
* @return A linear interpolation between the start and end values, given the
*fraction
parameter.
*/
public T evaluate(float fraction, T startValue, T endValue);
}
接口中就只有一个方法,用于计算在动画完成某个百分比fraction的时候,值是多少,而这个值就是当前属性动画针对的对象的属性值
我们可以看看实现的类,就看我们上述ofFloat方法所使用的默认的数值计算的实现类
public class FloatEvaluator implements TypeEvaluator {
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}
可以很轻松的看懂这两句代码
而前两个方法中为什么没有呢?
这是因为前两个方法的传入的值(前两个方法的第三个参数)是确定的,内部中自带了一个TypeEvaluation的实现类,这里不在深究
ObjectAnimator动画实现的原理
在上述代码中
第一个参数是一个View对象
第二个参数填写的是"rotation"
第三个参数是0, 90
你们知道为什么每个参数在其中的作用么?相信有很多人还是一知半解.
我们的效果是顺时针转动,在View中提供了一个方法来实现View的转动
view.setRotation(float rotation);
所以我们这个属性动画能产生效果的原因就是ObjectAnimator内部多次的通过反射调用View对象中的setRotation(float)方法,float的值从0变化到90
所以我们看到了旋转动画,其实就是不间断的改变View对象中的旋转值
而有的人可能还看到一个细节,那就是博主每一次的点击图片,动画还是和View Animation一样是从原来的状态开始的,其实是你理解错了,这是因为这里你传入的值就是每次从0开始到90的,所以每次动画开始都是这样子的
view.setRotation(0);
.
.
.
view.setRotation(90);
所以你每次都是看到从原来的状态开始的,如果你想要实现每次点击都是在旋转后的基础上进行旋转,就这么做
ObjectAnimator
.ofFloat(v, "rotation", v.getRotation(), v.getRotation() + 90)
.setDuration(2000)
.start();
看到代码应该懂了吧,后面的两个值,第一个永远都是view对象的当前旋转值,第二个是当前旋转值+90,,这样子就能实现每次点击旋转90°
文章图片
这效果用View Animation实现就比较吃力了吧,哈哈
懂原理之后的扩展效果
水平翻转
在View中提供了如下方法来水平旋转
v.setRotationX(float rotationX);
那么我们的属性名就可以填写"rotationX"
ObjectAnimator
.ofFloat(v, "rotationX", v.getRotationX(), v.getRotationX() + 70)
.setDuration(2000)
.start();
这里每次旋转70°,因为旋转90°就看不见了
文章图片
竖直翻转
和上述的同理所以不在陈述,只给出代码和效果
ObjectAnimator
.ofFloat(v, "rotationY", v.getRotationY(), v.getRotationY() + 70)
.setDuration(2000)
.start();
效果图
文章图片
混合效果
上述我们直接调用的是三个参数的方法,让属性动画框架去帮我们调用指定的方法,其实还有另一种方法
public void animation(final View v) {ValueAnimator objectAnimator = ObjectAnimator//
.ofFloat(v.getRotationY(), v.getRotationY() + 70)//
.setDuration(2000);
//设置更新数据的监听
objectAnimator.addUpdateListener(new AnimatorUpdateListener() {@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = https://www.it610.com/article/(Float) animation.getAnimatedValue();
v.setRotationY(value);
}
});
objectAnimator.start();
}
这个效果也是实现了竖直方向的翻转,但是代码实现的方式是不一致的.我们可以看到调用了ofFloat的重载方法,少传了对象target和属性名称property,那么这个动画开始之后并不会有任何的效果,但是还是会产生每个阶段的数据,所以会回调接口中AnimatorUpdateListener的更新数据的方法,所以在方法中我们自己就可以根据数据去设置view对象的竖直翻转的值
显然这种实现方式比较灵活,这里不仅可以实现竖直翻转,还可以同时实现多种动画了
比如我想要实现,水平方向和竖直方向一起翻转,那么对应的代码是
public void animation(final View v) {ValueAnimator objectAnimator = ObjectAnimator//
.ofFloat(v.getRotationY(), v.getRotationY() + 70)//
.setDuration(2000);
//设置更新数据的监听
objectAnimator.addUpdateListener(new AnimatorUpdateListener() {@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = https://www.it610.com/article/(Float) animation.getAnimatedValue();
//新添加的一句,就多了一个水平翻转的效果
v.setRotationX(value);
v.setRotationY(value);
}
});
objectAnimator.start();
}
【学习心得|Android 属性动画详解】
就多了一个代码,那么效果呢?
文章图片
ValueAnimator 其实ValueAnimator和上述的ObjectAnimator是非常类似的,你可以这样子理解
ObjectAnimator根据你传入的起始值和结束值来计算出轨迹数据来不断的改变对象中的某一个属性的值(反射调用set方法)
ValueAnimator只是根据你传入的起始值和结束值来计算出轨迹数据而已,自身不带有任何的效果,需要你自己监听数据的变化来改变某一个对象的数据来达到效果,这个和ObjectAnimator中最后一个混合效果的那个例子很相似的
所以这里就不再陈述了,请大家自己去多实践实践
那么今天的ObjectAnimation就介绍到这里啦,如果喜欢本篇博客或者有任何疑问,欢迎留言!
转载请注明出处:http://blog.csdn.net/u011692041/article/details/51471743