标签:
Google在3.0以后推出了属性动画,之所以会出属性动画,是因为传统动画在对象交互方面存在缺陷。
可以通过一个很经典的例子来发现属性动画和传统动画的区别。
先来看一个现象:
可以观察到:
传统动画播放完毕后,点击显示的view是没有响应产生的。说明view的属性并没有因为动画的变化而变化。
属性动画播放完毕后,点击显示的view是有响应产生的。说明view的属性跟随动画的变化改变了。
上述效果的实现的实现关键代码:
//传统动画 TranslateAnimation translateAnimation = new TranslateAnimation(0, 200, 0, 0); //新建位移动画 translateAnimation.setDuration(1000); //动画时长1秒 translateAnimation.setFillAfter(true); //动画完毕后画面保持动画结束的画面 imageView1.startAnimation(translateAnimation); //视图控件开始播放动画
//属性动画 //设置动画作用对象view、动画作用属性、属性变化起止 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView2, "translationX", 0F,200F); objectAnimator.setDuration(1000); //动画时长1秒 objectAnimator.start(); //属性动画开始播放
view animation system 提供的能力只能够为 View 添加动画。因此如果你想为非
View 对象添加动画,就必须自己去实现, view animation system 在 View 动画的展现方面也是有约束的,只暴露了 View 的很少方面。比如 View 支持缩放和旋转,但不支持背景颜色的动画。
view animation system 的另一劣势是,其改变的是 View 的绘制效果,真正的 View 的属性保持不变,比如无论你在对话中如何缩放 Button 的大小,Button 的有效点击区域还是没有应用到动画时的区域,其位置与大小都不变。
但是 View animation system 只需花费很少时间创建而且只需很少的代码。如果 View 动画完成了你所有的动作,或者你存在的代码已经达到了你想要的效果,就没必要使用 property 动画系统了。
完全弥补了 View anim System 的缺陷,你可以为一个对象的任何属性添加动画,(View
或者非 View),同时对象自己也会被修改。 并且当属性变化的时候,property Anim 系统会自动的刷新屏幕。
属性动画系统在处理动画方面也更加强劲。更高级的,你可以指定动画的属性,比如颜色,位置,大小,定义动画的插值器并且同步多个动画。
并且在 Property Animation 中,改变的是对象的实际属性,如 Button 的缩放,Button 的位置与大小属性值都改变了。而且 Property Animation 不止可以应用于 View,还可以应用于任何对象。
平时使用的简单动画特效,使用 View 动画就可以满足,但是如果你想做的更加复杂,比如背景色的动画,或者不仅是 View,还希望对其它对象添加动画等,那么你就得考虑使用 Property 动画了。
总结:属性动画Animator比传统动画Animation强大很多,但是我们如果能用Animation满足我们的需求,就没有必要使用Animator。
属性动画中的名词解释:
ValueAnimator
---数值发生器,可以实现很多很灵活的动画效果;
ObjectAnimator ---继承于ValueAnimator,可以很好滴使用属性对话框架;
AnimatorUpdateListener --- 用于动画监听器
AnimatorListenerAdapter--- 用于动画监听器
PropertyValuesHolder ---用于控制动画集合的显示效果
Animatorset ---用于控制动画集合的显示效果
TypeEvaluators ---值计算器,用于控制值变化的规律
Interprolators ---插值计算器,用于控制值变化的规律
组合动画实现方式一:
case R.id.button3: // 组合动画方式一:三个不同的属性动画一起开始播放 ObjectAnimator.ofFloat(imageView2, "translationX", 0F, 200F) .setDuration(1000).start(); // x轴平移动画 ObjectAnimator.ofFloat(imageView2, "translationY", 0F, -200F) .setDuration(1000).start(); // y轴平移动画 ObjectAnimator.ofFloat(imageView2, "rotation", 0F, 360F) .setDuration(1000).start(); // 旋转360度动画 break;
组合动画实现方式二:
case R.id.button4: // 组合动画方式二:使用PropertyValuesHolder将多个动画效果组装成一个属性动画(组合动画推荐此方式) PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat( "translationX", 0F, 200F); PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat( "translationY", 0F, -200F); PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat( "rotation", 0F, 360F); // 将上述三个动画效果组装成一个属性动画并播放 ObjectAnimator.ofPropertyValuesHolder(imageView2, pvh1, pvh2, pvh3) .setDuration(1000).start(); break;
组合动画实现方式三:
case R.id.button5: // 组合动画方式三:使用AnimatorSet集合来管理多个属性动画,并且能够灵活管理属性动画执行顺序(顺序动画推荐此方式) ObjectAnimator oa1 = ObjectAnimator.ofFloat(imageView2, "translationX", 0F, 200F).setDuration(1000);// x轴平移动画 ObjectAnimator oa2 = ObjectAnimator.ofFloat(imageView2, "translationY", 0F, -200F).setDuration(1000);// y轴平移动画 ObjectAnimator oa3 = ObjectAnimator.ofFloat(imageView2, "rotation", 0F, 360F).setDuration(1000); // 旋转360度动画 //新建属性动画集合 AnimatorSet as = new AnimatorSet(); //属性动画一起同时播放 as.playTogether(oa1,oa2,oa3); as.start(); /** * as.playSequentially(oa1,oa2,oa3); //属性动画顺序播放 * * as.play(oa1).with(oa2); //先播放1和2,后播放3 * as.play(oa3).after(oa1); * */
//为属性动画添加监听器 objectAnimator.addListener(new Animator.AnimatorListener(){ @Override public void onAnimationCancel(Animator arg0) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animator arg0) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animator arg0) { // TODO Auto-generated method stub } @Override public void onAnimationStart(Animator arg0) { // TODO Auto-generated method stub } });
但是一般情况下我们都只需要重写onAnimationEnd()方法,其它得代码是不需要的,android早已考虑到这个问题,我们可以使用下面这种方式实现动画监听:
//为属性动画添加监听器 objectAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Toast.makeText(PropertyAnimationActivity.this, "动画播放完毕...", Toast.LENGTH_SHORT).show(); super.onAnimationEnd(animation); } });
线性变化代码:
case R.id.button6: //线性变化 ValueAnimator va1 = ValueAnimator.ofInt(1,100).setDuration(3000); //创建一个数值发生器对象,变化从1至100 //为数值发生器添加一个数值更新监听器 va1.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { // 当数值发生变化的时候 ,把当前值读取出来 Integer i = (Integer) valueAnimator.getAnimatedValue(); // 显示到textview上去 textView1.setText(""+i); } }); //默认情况下就是数值就是线性变化,直接开始 va1.start(); break;
减速变化代码:
case R.id.button7: //减速变化 ValueAnimator va2 = ValueAnimator.ofInt(1,100).setDuration(3000); //创建一个数值发生器对象,变化从1至100 //设置减速插值器 va2.setInterpolator(new DecelerateInterpolator()); //为数值发生器添加一个数值更新监听器 va2.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { // 当数值发生变化的时候 ,把当前值读取出来 Integer i = (Integer) valueAnimator.getAnimatedValue(); // 显示到textview上去 textView1.setText(""+i); } }); //开始 va2.start(); break;
标签:
原文地址:http://blog.csdn.net/bear_huangzhen/article/details/51916015