Android属性动画-Property Animation(二) 使用ObjectAnimator完成动画

     上一篇文章中我们分析了属性动画的工作原理,这篇文章开始介绍属性动画的实现,就不会再去分析原理,如果对原理不清楚的朋友可以看一下 Android属性动画-Property Animation(一) 原理分析

       使用属性动画时我们通常使用Animator的两个子类,ValueAnimatorObjectAnimator。这两个子类如何选择呢?在大多数情况下我们会使用ObjectAnimator,它比较轻量级,使用非常简单,但是它也有一些局限性,就是必须要实现属性的getter和setter方法,因为使用ValueAnimator的时候我们必须实现ValueAnimator.AnimatorUpdateListener接口,并且在onAnimationUpdate()里面手动更新属性值,而ObjectAnimator不用,那么他就必须要通过setter方法自动给属性赋值,getter方法自动获得属性的值。


       因为ObjectAnimator使用的比较多,使用起来又比较简单,我们就先来分析一下ObjectAnimator怎么使用吧


       其实ObjectAnimatorValueAnimator的一个子类,既然google这样设计,那么它肯定进行了某方面的优化,我们上面已经提到了,使用ObjectAnimator不用再去实现ValueAnimator.AnimatorUpdateListener接口了,因为他会自动去更新属性值。
我们先来看一个简单的例子:

Android属性动画-Property Animation(二) 使用ObjectAnimator完成动画_第1张图片

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
            
/**
* 作者: 阿拉灯神灯
* 主页:http://blog.csdn.net/nugongahou110
* 日期:2015.07.02
*/
public class MainActivity extends Activity {
private Button mButton ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView ( R . layout . activity_main );
mButton =( Button ) findViewById ( R . id . start_my_anim );
mButton . setOnClickListener ( new OnClickListener () {
@Override
public void onClick ( View v ) {
//新建一个ObjectAnimator实例,使用它的静态方法ofFloat
//第一个参数是要执行动画的对象
//第二个参数是要改变属性的名称
//第三个参数是属性的初始值,第四个参数是属性的结束值
ObjectAnimator anim = ObjectAnimator . ofFloat ( mButton , "scaleY" , 1.0f , 3.0f );
// ObjectAnimator anim = ObjectAnimator.ofFloat(mButton, "scaleY", 3.0f);
// ObjectAnimator anim = ObjectAnimator.ofFloat(mButton, "scaley", 3.0f);
//设置一个TimeInterpolator为弹球效果
anim . setInterpolator ( new BounceInterpolator ());
//设置动画持续时间
anim . setDuration ( 2000 );
//开始动画
anim . start ();
}
});
}
}
 来自CODE的代码片
MainActivity.java

我们看上面代码中的“scaleY”,这是怎么来的呢?不是说ObjectAnimator需要给属性设置setter/getter方法吗?我们也没设置啊,怎么也可以执行?
带着这些疑问我们一步一步去分析一下,首先执行动画的是一个Button,Button是继承自TextView的,TextView是继承自View的。我们到View中去看一看。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
            
public void setScaleX ( float scaleX ) {
ensureTransformationInfo ();
final TransformationInfo info = mTransformationInfo ;
if ( info . mScaleX != scaleX ) {
invalidateViewProperty ( true , false );
info . mScaleX = scaleX ;
info . mMatrixDirty = true ;
invalidateViewProperty ( false , true );
if ( mDisplayList != null ) {
mDisplayList . setScaleX ( scaleX );
}
if (( mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED ) == PFLAG2_VIEW_QUICK_REJECTED ) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded ();
}
}
}
public float getScaleX () {
return mTransformationInfo != null ? mTransformationInfo . mScaleX : 1 ;
}
 来自CODE的代码片
View.java
果然,在View中已经写好了scaleY的setter和getter方法,不用我们自己去写了。除此之外,View中还已经写好了setAlpha()、setX()、setScaleX()、setTranslationX()等setter方法和对应的getter方法,我们可以拿来就用,其实这些不就是View Animation中的淡入淡出,平移,放大缩小等动画吗!
       Note:如果将第24行注释掉,执行第25行。我们发现后面只有一个参数3.0f,属性的初始值没有了,照样可以执行!ObjectAnimator可以自动调用getter方法,获得当前属性的值,这就是为什么一定要有getter方法!如果将24、25行都注释掉,执行第26行,那就该报错了,因为View中没有一个"scaley"这个属性,只有"scaleY"。大小写非常重要!具体命名规则见下例

但是作为属性动画,号称是可以改变任意一个属性的,那么我们就来自定义一个属性,看看属性动画的威力!
首先我们自定义一个布局,它继承自View,目的就是画出一个数字在屏幕上
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 
             
public class TempView extends View {
//新建一个画笔
private Paint paint = new Paint ();
//这个就是在屏幕上显示的数字
private int mCurnum = 0 ;
public TempView ( Context context , AttributeSet attrs , int defStyle ) {
super ( context , attrs , defStyle );
}
public TempView ( Context context , AttributeSet attrs ) {
super ( context , attrs );
}
public TempView ( Context context ) {
super ( context );
}
//setter方法,这个方法必须要有,而且命名规则不能错!
//我们在启动动画的时候,传进去了一个字符串表示要计算的属性
//ObjectAnimator anim = ObjectAnimator.ofInt(mView,"curnum",100);
//就是"curnum"! 那么根据命名规则,我们就要写一个setCurnum()方法,系统会自动找到这个setter方法
//如果我们传入的字符串为"aladengshendeng",那么我们就要写一个setAladengshendeng()方法
//明白了吧,只要将首字母大写后的字符串加在set的后面,这个setter方法的命名才是正确的!!
public void setCurnum ( int currnum ){
mCurnum = currnum ;
//这个invalidate方法一定要有!!它会重新调用onDraw()方法。这个是通知系统我的属性已经改变!你要将我重画!
invalidate ();
}
//getter方法,这个方法必须要有,命名规则同setter方法
public float getCurnum (){
return mCurnum ;
}
@Override
protected void onDraw ( Canvas canvas ) {
// super.onDraw(canvas);
paint . setStrokeWidth ( 8 );
paint . setTextSize ( 100 );
canvas . drawText ( String . valueOf ( mCurnum ), 100 , 100 , paint );
}
}
 来自CODE的代码片
TempView.java
布局文件
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
              
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:id= "@+id/mView"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
/>
android:id= "@+id/bt_start_animation"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentBottom= "true"
android:layout_alignParentRight= "true"
android:text= "start!" />
 来自CODE的代码片
main_activity.xml
最后是MainActivity
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 
              
public class MainActivity extends Activity {
private TempView mView ;
private Button startAnimation ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView ( R . layout . activity_main );
mView =( TempView ) findViewById ( R . id . mView );
startAnimation =( Button ) findViewById ( R . id . bt_start_animation );
startAnimation . setOnClickListener ( new OnClickListener () {
@Override
public void onClick ( View v ) {
//新建一个ObjectAnimator实例,调用静态方法ofInt()
//第一个参数是要执行动画的对象,即我们自定义的TempView
//第二个参数是我们想要改变的属性名,TempView中要有相应的setter/getter方法
//第三个参数是我们给定curnum的结束值,至于为什么没有开始值,以及需不需要有开始值,请参看上面的例子
ObjectAnimator anim = ObjectAnimator . ofInt ( mView , "curnum" , 100 );
//设置动画的持续时间
anim . setDuration ( 5000 );
//设置一个TimeInterpolator为减速
anim . setInterpolator ( new DecelerateInterpolator ());
//开始动画
anim . start ();
}
});
}
}
 来自CODE的代码片
MainActivity.java
最后的效果:
Android属性动画-Property Animation(二) 使用ObjectAnimator完成动画_第2张图片

怎么样,属性动画很厉害吧。这可是View Animation做不了的!

 ObjectAnimator我们就分析完了,下一篇我们来分析ValueAnimator Android属性动画-Property Animation(三) 使用ValueAnimator完成动画 



版权声明:欢迎转载,转载请注明出处http://blog.csdn.net/nugongahou110

你可能感兴趣的:(android)