(一)简介
属性动画是Android 3.0中提供了新功能,便于对任意元素进行“平滑的过渡”。众所周知,Android 之前提供的补间动画如AlphaAnimation、TranslateAnimation等都只能应用在View上,并且几乎没有任何可扩展的地方。并且,使用原来的动画无法实现颜色渐变效果,算是一个遗憾。
属性动画彻底打破了这种设计方式,不再将这些动画强制的放在View上,而是仅仅产生一系列的值,由开发人员自行使用这些值。例如,属性动画可产生1~0平滑过渡的值,把这些值应用在View的alpha上就可以实现透明度渐变了。
同时,属性动画可以直接用来改变View的属性。例如,不断的setTranslationX,便可实现水平方向的平移。
(二)代码演示
1.ValueAnimator:产生某个范围内平滑过渡的值。
//属性动画,0~1渐变 public void simpleValueAnimator(View view) { ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); anim.setDuration(300); //动画过程的监听 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //回调方法在主线程执行 float currentValue = (float) animation.getAnimatedValue(); Log.d(TAG, "current value is " + currentValue); } }); anim.start(); }(1)该方法可以通过设置多个值来实现更复杂的“平滑过渡”,例如实现0~5~3~10的过渡效果:
ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f);(2)设置启动延时、重复次数、重复模式:
//设置启动延时 anim.setStartDelay(1000); //设置重复次数(也可以设置成无限次数) anim.setRepeatCount(3); //设置重复模式:重新执行动画(也可以设置成倒序) anim.setRepeatMode(ValueAnimator.RESTART);(3)监听动画开始、结束、重复状态:
//监听动画的状态(开始/结束/重复/取消) anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); Log.d(TAG, "onAnimationStart"); } @Override public void onAnimationRepeat(Animator animation) { super.onAnimationRepeat(animation); Log.d(TAG, "onAnimationRepeat"); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); Log.d(TAG, "onAnimationEnd"); } });2.ObjectAnimator:平滑的改变任意对象的属性值。
(1)平滑改变TextView的不透明度:
public void changeAlphaValue(View view) { TextView textView = (TextView) findViewById(R.id.main_text1); //ObjectAnimator继承自ValueAnimator //animator会调用textView的setAlpha方法。如果该方法不存在则会出现警告异常。 ObjectAnimator animator = ObjectAnimator.ofFloat(textView, "alpha", 1f, 0f, 1f); animator.setDuration(3000); animator.start(); }该动画并非直接改变textView的alpha属性(事实上,textView甚至它的父组件View都没有alpha属性),而是调用textView的setAlpha方法,然后传入1~0~1平滑渐变的值作为参数,从而实现了不透明度渐变效果。
类似的,可以通过传递参数rotation、translationX(translationY)等实现旋转、平移等效果。
3.使用AnimatorSet将各个动画进行组合:
public void animatorSet(View view) { TextView textView = (TextView) findViewById(R.id.main_text1); ObjectAnimator moveIn = ObjectAnimator.ofFloat(textView, "translationX", -500f, 0f); ObjectAnimator rotate = ObjectAnimator.ofFloat(textView, "rotation", 0f, 360f); ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textView, "alpha", 1f, 0.2f, 1f); //先平移,然后在旋转的同时进行alpha渐变 AnimatorSet animSet = new AnimatorSet(); animSet.play(rotate).with(fadeInOut).after(moveIn); animSet.setDuration(5000); animSet.start(); }animSet.play会产生一个Animator.Builder对象,然后可以使用with,after,before等方法进行动画叠加。
4.自定义Evaluator,实现任意两个对象之间的“平滑过渡”。
ValueAnimator的ofInt,ofFloat方法很简单,无非是产生一些平滑过渡的数值。不过,ValueAnimator还有一个ofObject方法,可以实现两个Object之间的平滑过渡。显然,系统不可能知道应该怎么过渡,因此需要我们指定它。
例如定义了一个类表示点的坐标:
public class PointBean { private float x; private float y; public PointBean(float x, float y) { this.x = x; this.y = y; } public float getX() { return x; } public void setX(float x) { this.x = x; } public float getY() { return y; } public void setY(float y) { this.y = y; } }然后,我们希望实现两个点之间的平滑过渡(通过它就可以实现View的平移了),就需要定义两个PointBean之间是如何过渡的。当然此处的实现很简单:
public class PointEvaluator implements TypeEvaluator<PointBean> { @Override public PointBean evaluate(float fraction, PointBean startValue, PointBean endValue) { float x = startValue.getX() + fraction * (endValue.getX() - startValue.getX()); float y = startValue.getY() + fraction * (endValue.getY() - startValue.getY()); return new PointBean(x, y); } }参数fraction表示动画完成度(0.0~1.0的一个值),startValue表示开始点,endValue表示结束点,该方法需要返回从startValue过渡到endValue、完成比例是fraction时的结果。
ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint); animator.setDuration(2000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointBean current = (PointBean) animation.getAnimatedValue(); imageView.setTranslationX(current.getX()); imageView.setTranslationY(current.getY()); } }); animator.start();5.实现颜色渐变
与上述内容相似,实现红色~绿色~蓝色的渐变:
ValueAnimator animator = ValueAnimator.ofObject(new ColorEvaluator(), "#ffff0000", "#ff00ff00", "#ff0000ff"); animator.setDuration(5000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { String currentColor = (String) animation.getAnimatedValue(); textView.setBackgroundColor(Color.parseColor(currentColor)); } }); animator.start();显然此处的重点是ColorEvaluator,即指定颜色值是如何渐变的。例如, #ffff0000是如何过渡到#ff00ff00的。
public class ColorEvaluator implements TypeEvaluator<String> { //仅支持AARRGGBB模式 @Override public String evaluate(float fraction, String startValue, String endValue) { if (!startValue.startsWith("#") || !endValue.startsWith("#")) { throw new IllegalArgumentException("color must started with '#'."); } if (startValue.length() != 9 || endValue.length() != 9) { throw new IllegalArgumentException("startValue and endValue must be '#AARRGGBB'."); } int start_a, start_r, start_g, start_b; int end_a, end_r, end_g, end_b; //start start_a = getIntValue(startValue, 1, 3); start_r = getIntValue(startValue, 3, 5); start_g = getIntValue(startValue, 5, 7); start_b = getIntValue(startValue, 7, 9); //end end_a = getIntValue(endValue, 1, 3); end_r = getIntValue(endValue, 3, 5); end_g = getIntValue(endValue, 5, 7); end_b = getIntValue(endValue, 7, 9); return "#" + getHexString((int) (start_a + fraction * (end_a - start_a))) + getHexString((int) (start_r + fraction * (end_r - start_r))) + getHexString((int) (start_g + fraction * (end_g - start_g))) + getHexString((int) (start_b + fraction * (end_b - start_b))); } //从原始#AARRGGBB颜色值中指定位置截取,并转为int. private int getIntValue(String hexValue, int start, int end) { return Integer.parseInt(hexValue.substring(start, end), 16); } private String getHexString(int value) { String a = Integer.toHexString(value); if (a.length() == 1) { a = "0" + a; } return a; } }6.设置Interpolator,控制动画进行的方式,如匀速、逐渐加速、逐渐减速或先加速后减速等效果。此处和传统的动画很相似。同样,可以自定义Interpolator的实现。
anim.setInterpolator(new AccelerateInterpolator()); //逐渐加速的动画7.ViewPropertyAnimator:使用属性动画为View设置动画效果的一种简便方式。
testImageView.animate().setDuration(2000).alpha(0.3f).rotationBy(360).yBy(160);上述代码表示将testImageView的不透明度渐变至0.3,同时旋转360度、向下移动160px。
这里的方法都有两种形式,如rotation(360)表示旋转至360度的位置(不管起始状态是多少度,都旋转至360度),而rotationBy(360)表示旋转360度(如果起始位置不是0度,则结束时依然不是0度)。
原文地址:http://blog.csdn.net/books1958/article/details/46518797