Property Animation介绍:
出生在3.0,是利用了View所拥有的属性,进行一系列的操作。比如一个View有什么样的setAbc的属性,那么理论上就可以设置它。
它不仅改变View的绘制,也改变了View的属性;而Tween Animation 只改变View的绘制。
ValueAnimator 为动画的基类,它有一个子类ObjectAnimator。需要Interpolator和TypeEvaluator来计算属性值。
Interpolator 时间插入器,动画的运动速率,参见上一篇Tween Animation
TypeEvaluator Animator的工厂方法 of方法能创建属性为任何值类型的对象。TypeEvaluator就是用来计算属性值的
3.0以后新增了一些View的属性:
1)translationX 和 translationY:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。
2)rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)旋转。它的表现跟Tween Animation中的RotateAnimation不一致。
RotateAnimation 的旋转,表现为平面的旋转
而rotationX、Y 旋转,是立体的旋转,默认是以View的中心点,做x y的水平线,面向水平线进行翻转
3)scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。
4)pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
5)x 和 y:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。
6)aplha:透明度,1是完全不透明,0是完全透明。
以上这些属性与Tween Animation的动画属性值差不多
ObjectAnimator 对象动画
该动画,一次只能表示一个动作属性。
ObjectAnimator的xml实现
xml定义动画
res/animator/scale_object_animator.xml
<?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="2000" android:propertyName="scaleX" android:repeatCount="1" android:repeatMode="reverse" android:valueFrom="1.0" android:valueTo="2.0" > </objectAnimator>
代码加载 动画xml
imageview_scale.setBackground(getResources().getDrawable(R.drawable.a11)); ObjectAnimator scaleAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.scale_object_animator); scaleAnimator.setTarget(imageview_scale);//设置动画作用的目标对象 scaleAnimator.setDuration(1000); scaleAnimator.setRepeatCount(50); scaleAnimator.start();
AnimatorSet 动画集
由ObjectAnimator 和 ValueAnimator 组成,对应的xml中的写法 类似为 <se> <objectAnimator /> <animator /> </set>
xml定义动画
res/animator/set_rotate_scale.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <set> <objectAnimator android:propertyName="rotationX" android:repeatCount="50" android:repeatMode="reverse" android:valueFrom="0" android:valueTo="20" /> <objectAnimator android:propertyName="rotationY" android:repeatCount="50" android:repeatMode="reverse" android:valueFrom="0" android:valueTo="45" android:valueType="floatType" /> </set> <set> <objectAnimator android:propertyName="scaleX" android:repeatCount="50" android:repeatMode="reverse" android:valueFrom="1.0" android:valueTo="2.0" > </objectAnimator> <objectAnimator android:propertyName="scaleY" android:repeatCount="50" android:repeatMode="reverse" android:valueFrom="1.0" android:valueTo="2.0" > </objectAnimator> </set> </set>
代码加载 动画xml
imageview_rotate.setBackground(getResources().getDrawable(R.drawable.a11)); AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.set_rotate_scale); animatorSet.setTarget(imageview_rotate); animatorSet.setDuration(1000); animatorSet.setInterpolator(new BounceInterpolator());//设置end时的弹跳插入器 animatorSet.start();
PropertyValuesHolder
//使用PropertyValuesHolder 构造 Animator 组合成类似set的效果 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX",0f,2.5f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY",0f,3f); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageview, pvhX,pvhY); animator.setDuration(2000); animator.start();
ViewPropertyAnimator
通过view.animate()来获取ViewPropertyAnimator
imageview.setBackground(getResources().getDrawable(R.drawable.a11)); ViewPropertyAnimator animate = imageview.animate();//该对象没有setRepeat的方法 //通过一些动画属性来设置 组合成类似set的效果 animate.alpha(0); animate.rotationX(50); animate.translationXBy(500); animate.scaleX(1.5f); animate.scaleY(1.5f); animate.setInterpolator(new BounceInterpolator()); animate.setDuration(2000); animate.start();
ValueAnimator
ValueAnimator代码和xml设置中 没有setPropertyName 因为不是操作对象,只是根据value进行某种动作
需要加监听器,监听值的变化 做相应的处理
xml定义动画
<?xml version="1.0" encoding="utf-8"?> <animator xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" android:duration="10000" android:startOffset="1000" android:repeatCount="infinite" android:repeatMode="restart" android:valueFrom="1" android:valueTo="100" android:valueType="intType"> </animator>
代码加载 动画xml
ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator); valueAnimator.setTarget(tv_num); valueAnimator.setEvaluator(new TypeEvaluator<Integer>() { @Override public Integer evaluate(float fraction, Integer startValue, Integer endValue) { System.out.println("百分比,fraction:" + fraction); System.out.println("结果值:" + (int)((startValue + fraction * (endValue - startValue)) / 10 * 10)); return (int)((startValue + fraction * (endValue - startValue)) / 10 * 10); } }); valueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //在onAnimationUpdate中 该值返回第一个动画的 当前帧的evaluate 值 System.out.println("animation.getAnimatedValue()==" + animation.getAnimatedValue()); tv_num.setText(animation.getAnimatedValue() + ""); } }); // valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.start();
Animator的监听器
AnimatorListener
new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } }
AnimatorListenerAdapter
new AnimatorListenerAdapter() {//空实现了AnimatorListener @Override public void onAnimationCancel(Animator animation) { super.onAnimationCancel(animation); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); } @Override public void onAnimationRepeat(Animator animation) { super.onAnimationRepeat(animation); } @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); } @Override public void onAnimationPause(Animator animation) { super.onAnimationPause(animation); } @Override public void onAnimationResume(Animator animation) { super.onAnimationResume(animation); } }
AnimatorUpdateListener
new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //在onAnimationUpdate中 该值返回第一个动画的 当前帧的evaluate 值 System.out.println("animation.getAnimatedValue()==" + animation.getAnimatedValue()); } }
一些操作函数:animator.pause(); animator.resume();animator.reverse(); animator.end();animator.cancel();
animator.start();animator.isStarted();animator.isPaused();animator.isRunning();
用属性动画换背景色
详见ApiDemo要下的 BouncingBalls.java
private static final int RED = 0xffFF8080; private static final int BLUE = 0xff8080FF; private static final int CYAN = 0xff80ffff; private static final int GREEN = 0xff80ff80; { //动画 变色 ObjectAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", CYAN, BLUE, RED); colorAnim.setTarget(ll_animation); colorAnim.setEvaluator(new ArgbEvaluator()); colorAnim.setRepeatCount(ValueAnimator.INFINITE); colorAnim.setRepeatMode(ValueAnimator.REVERSE); colorAnim.setDuration(3000); colorAnim.start(); }