Android-Preproty animation解析
来源:互联网 发布:商品标题搜索优化 编辑:程序博客网 时间:2024/05/02 02:19
android-Property Animation介绍
属性动画(property animation)系统,是一个健壮的框架,可以实现任何将任何属性设置为动画。不管对象是否被绘制到屏幕上,你都可以声明一个动画去改变它的属性值。属性动画是指在定长时间内改变指定属性的一种动画。
你可以从下面这些特性入手去定义一个属性动画(property animation):
- Duration(持续时间):你可以指定动画的持续时间,默认值为300ms
- Time interpolation(时间插值器):你可以指定属性值和动画已执行时间之间的换算方法
- Repeat count and behavior(动画重复次数和重复的方式):你可以指定动画的重复次数。同时,你也可以指定动画重复的模式,例如是从头到尾从头到尾的效果,还是重头到尾再从尾到头。
- Animator sets(动画集合):你可以将一系列动画都放入一个动画集合中。之后,通过设置动画集合,以同时或有序或指定掩饰的方式播放那一系列的动画。
- Frame refresh delay(帧刷新时间):你可以指定播放动画时,刷新屏幕的时间间隔。默认刷新时间是10ms,但是具体有系统决定。
属性动画工作流程
先来看一个简单的例子,图1描述了一个拥有改变x属性的动画的对象,图中x轴坐标系与屏幕表面平行。动画持续40ms,每10ms,屏幕刷新一次,同时对象向x轴坐标方向前进10像素点。在40ms结束之后,动画停止,对象停留在x轴坐标为40的位置。这个例子,其实采用的是一个linear interpolation,抽象类指定属性匀速变化。
图1.线性动画实例
介绍了线性动画,接下来让我们来看看非线性动画吧。图2为同样也是描述了一个拥有沿x轴运动动画的对象。不同之处在于,动画不是匀速运动,而是一开始先加速,到快结束时减速的动画。这个动画也是在40ms内运动了40像素点,但不是线性运动。从图中可以看出,动画从起始点到中点进行加速;之后,从中点到结束点进行减速。
图2.非线性动画实例
通过图3,详细介绍属性动画是怎么实现的。
图3.实现原理图
详细介绍:
其中的ValueAnimator是动画的执行类,跟踪了当前动画的执行时间和当前时间下的属性值;ValueAnimator封装了动画的TimeInterpolator和TypeEvaluator。TypeEvaluator用来计算设置动画属性的值。例如图2中,动画采用TimeInterpolator是AccelerateDecelerateInterpolator,然后TypeEvaluator是IntEvaluator。
为了执行一个动画,需要创建一个ValueAnimator对象并指定目标对象的开始值,结束值和持续时间。在调用star()方法后,动画开始。在整个动画过程中,ValueAnimator对象计算动画执行进度百分数,动画进度从0~1。当动画刚刚开始的时候,进度为0,%0;当动画结束时,进度为1,%100。例如图1,当执行了10ms之后,进度为0.25,因为从时间为40ms。
当ValueAnimator算出了动画执行进度之后,ValueAnimator调用当前设置的TimeInterpolator接口对象,去计算interpolator插值(0~1之间)。TimeInterpolator对象通过一定函数将动画执行进度转化为插值分数。例如图2,动画一开始速度比较慢;当动画执行10ms时,动画执行进度为0.25,插值分数为0.15。在比如图1,动画为线性动画,当动画执行10ms时,动画执行进度与插值分数始终相等。
当插值分数计算完成后,ValueAnimator会根据插值分数调用合适的 TypeEvaluator去计算运动中的属性值。例如图2,在动画执行10ms后,动画进度为0.15,动画属性值为:0.15*(40-0),6。
官方例子:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html
Property Animation和View Animation不同之处
View Animation只作用于View类及其子类,并且View Animation只作用于视图的位置,大小,旋转,透明度这4方面。View Animation只能改变View被绘制的位置和形式,对View本身属性不做任何改变。
在上面那些方面,Property Animation对View Animation补充。Property Animation可以对任何对执行动画,同时动画属性值真正的发生了变化。
API Overview
**表1**Animator动画执行类
表2 Evaluators(估值)
**表3**Interpolators(插值器)
介绍了那么多的概念,我们还是得回归到实践中去。毕竟理论源于实践嘛~
接下来,我们从最简单的ObjectAnimator开始,毕竟ObjectAnimator是系统已经给我们封装好了的类。
ObjectAnimator动画例子
布局文件
后面所有例子,都采用此布局文件
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="0dp" tools:context="com.example.abe.propertyanimation.MainActivity"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Hello World!" /></RelativeLayout>
Activity代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(this); } public void onClick(View v) {// 实现单个属性值改变动画// ObjectAnimator// .ofFloat(button, "x", 100F)// .setDuration(500)// .start();// 实现多个属性值改变动画 PropertyValuesHolder pvhAlpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0f); PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x",1f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y",1f); ObjectAnimator. ofPropertyValuesHolder(button, pvhAlpha, pvhX, pvhY) .setDuration(1000) .start(); }}
在Onclick方法在,实现了多属性动画代码和单属性动画代码。下面是他们的实现效果图
ObjectAnimator总结
提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。
当对于属性值,只设置一个的时候,会认为当然对象该属性的值为开始(getPropName反射获取),然后设置的值为终点。如果设置两个,则一个为开始、一个为结束
动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~
如果你操作对象的该属性方法里面,比如上例的setRotationX如果内部没有调用view的重绘,则你需要自己按照下面方式手动调用。
anim.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { view.postInvalidate(); view.invalidate(); } });
ValueAnimator动画例子
ValueAnimator动画例子中使用的布局,还是采用ObjectAnimator例子中的布局。
java代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View v) { ValueAnimator animator = new ValueAnimator(); animator.setObjectValues(new PointF(0, 0)); animator.setTarget(button);// 模拟线性插值器 animator.setInterpolator(new TimeInterpolator() { @Override public float getInterpolation(float input) { return input; } });// 自定义抛物线 animator.setEvaluator(new TypeEvaluator<PointF>() { // fraction = t / duration @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { PointF point = new PointF(); point.x = 200 * fraction * 3; point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3); return point; } });// 监听动画更新,同时设给对应属性值 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF point = (PointF) animation.getAnimatedValue(); button.setX(point.x); button.setY(point.y); } }); animator.setDuration(1000).start(); }}
ValueAnimator总结
通过上面的ValueAnimator动画例子,我们实现了自定义ValueAnimator动画的一个完成过程。其实这个动画工作流程,我们在一开始的属性动画工作流程
中已经讲过了,下面结合代码深入说明。
实现ValueAnimator动画,总计为4步:
- 创建ValueAnimator对象。
设置Interpolator(插值器),插值器,主要用于计算插值。ValueAnimator调用TimeInterpolator类中的
public float getInterpolation(float input)
方法,计算interpolator插值(0~1之间)。关于插值的计算方法,我们此方法中自定义实现。/* * @param 参数input为ValueAnimator提供的动画完成进度值 * @return 返回值为动画插值 public float getInterpolation(float input){}
如果我们不自定义Interpolator(插值器),也可以使用系统提供的插值器,插值器在表3中已经列出来了。常用插值器,设置方法
animator.setInterpolator(new LinearInterpolator());
设置TypeEvaluator(类型估值),主要用于计算属性值,ValueAnimator会根据插值分数调用evaluator去计算运动中的属性值。在例子中,我们是自定义的方式,来计算运动中的属性值。实现TypeEvaluator自定义,我们需要实现下面方法。
/* * @param 参数fraction为刚才Interpolator(插值器)计算出来的插值 * @param 参数startValue为动画开始值(本方法不作使用) * @param 参数endValue为动画结束值(本方法不作使用) * @return 计算得到的动画属性值 public PointF evaluate(float fraction, PointF startValue, PointF endValue) { PointF point = new PointF(); point.x = 200 * fraction * 3; point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3); return point; }
此方法作用,就是通过计算,将之前计算出来的插值变成动画属性值。
如果满足条件,我们也可以使用系统提供的TypeEvaluator。在表3中已经列出了系统提供的类型估值。常用类型估值,设置方法如下:
animator.setEvaluator(new IntEvaluator());
设置属性值。将TypeEvaluator中计算出来的动画属性值赋值给对象。在ObjectAnimator中,系统为我们做好了这一步,但是在ValueAnimator中我们需要自己来完成。下面是完成方法:
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //我们也可以将属性值,设置给多个对象,或者一个对象的多个值 //设置完全自定义的 PointF point = (PointF) animation.getAnimatedValue(); button.setX(point.x); button.setY(point.y); } });
AnimatorSet动画例子
布局,还是原来的布局~
java代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View v) {// ObjectAnimator anim1 = ObjectAnimator.ofFloat(button, "x", 0f);// ObjectAnimator anim2 = ObjectAnimator.ofFloat(button, "y", 0f);// AnimatorSet animSet = new AnimatorSet();// animSet.setDuration(2000);// animSet.setInterpolator(new LinearInterpolator());// //两个动画同时执行// animSet.playTogether(anim1, anim2);// animSet.start(); ObjectAnimator anim1 = ObjectAnimator.ofFloat(button, "x", 0f); ObjectAnimator anim2 = ObjectAnimator.ofFloat(button, "y", 0f); ObjectAnimator anim3 = ObjectAnimator.ofFloat(button, "alpha", 1f, 0f); AnimatorSet animSet = new AnimatorSet(); animSet.setDuration(2000); animSet.setInterpolator(new LinearInterpolator()); //三个动画执行顺序:anim1 -> anim2 -> anim3 animSet.play(anim1).before(anim2); animSet.play(anim3).after(anim2); animSet.start(); }}
在此例子中,我们实现了两个动画集合。其中,注释掉部分,两个动画同时执行;而没注释部分,则是按照anim1 -> anim2 -> anim3的顺序执行的。下面是效果图:
AnimatorSet总结
AnimatorSet设置动画执行顺序,常用方法介绍:
表4
参考
http://developer.android.com/intl/zh-cn/guide/topics/graphics/prop-animation.html#views
- Android-Preproty animation解析
- Android Animation 用法解析
- Android Animation 动画解析
- Android Animation 动画解析
- android animation解析
- android之animation解析一
- android动画(Animation)解析
- Android API 包解析02-android.animation
- Android Animation动画解析,参数说明
- Android属性动画(property animation)完全解析
- Android Animation各种动画完全解析
- Android Animation各种动画完全解析
- Android开发学习之Animation之Android帧动画解析
- Android -animation-Property Animation
- Android-animation-View Animation
- Android-animation-drawable Animation
- Android 属性动画(Property Animation) 完全解析 (下) 标签: AndroidProperty Animation
- Android ApiDemos示例解析(3): App->Activity->Animation
- 关于Hive的练习
- Amazon 亚马逊增加 Gamecircle注意事项
- 设置加载失败,正在加载,界面。
- 问与答——人物传记推荐
- 常见排序算法的Java实现代码汇总
- Android-Preproty animation解析
- Android项目实战--【谁是歌手-逻辑实现篇】
- 拥有大量相同结构Activity的项目精简经验—— ReUsableActivity
- ConcurrentHashMap原理分析
- BZOJ2038 2009国家集训队 小Z的袜子(hose) 题解&代码
- 解决Genymotion无法下载虚拟设备的问题
- 2016年算法之大数乘法
- jstack线程状态分析
- Android---universal-image-loader应用