ObjectAnimator是最常用的屬性動畫,他能直接作用在對象上實現(xiàn)動畫。
概覽
先看一下屬性動畫的結(jié)構(gòu),View動畫的基類是Animation,屬性動畫的基類是Animator

- ValueAnimator:這個動畫是針對屬性的值進行動畫的 ,不會對UI造成改變,不能直接實現(xiàn)動畫效果。需要通過對動畫的監(jiān)聽去做一些操作,在監(jiān)聽中將這個值設(shè)置給對應(yīng)的屬性,對應(yīng)的屬性才會改變。
- ObjectAnimator:直接動畫所給的對象,他會調(diào)用對象對應(yīng)屬性的get/set方法吧屬性的值設(shè)置給對象的屬性,直接實現(xiàn)動畫效果。
- TimeAnimator:這個也不直接實現(xiàn)動畫效果,只是提供一個監(jiān)聽回調(diào),返回動畫執(zhí)行的總時間,距離上次動畫執(zhí)行的時間等。
由圖可以看出,ObjectAnimator是從ValueAnimator中繼承出來的,因此ValueAnimator的屬性方法他都有。
在ValueAnimator中需要在動畫變化監(jiān)聽中手動更改對象的屬性,是動畫的使用有一種分裂的感覺。用動畫肯定是像讓眼睛能看見的界面動起來的,而不僅僅是讓看不見的數(shù)值動。ObjectAnimator就把這個過程整合在了一起。
基本使用
ObjectAnimator的初始化也是通過一系列ofXXX()方法來進行,但是參數(shù)有所變化,他的這些方法都要求傳入一個Object對象,然后就會在這個對象上執(zhí)行動畫。這個沒毛病,不給他對象他怎么知道給哪個對象動畫呢?
先看一個最簡單的方法ofInt(Object target, String propertyName, int... values):
有這樣的布局:
<Button
android:id="@+id/btn_start"
android:text="開始動畫"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_show"
android:layout_below="@+id/btn_start"
android:text="展示"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
然后執(zhí)行屬性動畫:
final ObjectAnimator objectAnimator = ObjectAnimator.ofInt(btnShow,"textColor",0xffffffff,0xffff0000);
objectAnimator.setDuration(3000);
objectAnimator.setRepeatCount(Animation.INFINITE);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
objectAnimator.start();
}
});
效果,圖片無限循環(huán)的閃爍:

屬性動畫有些可以鏈式調(diào)用,如下面直接開始動畫:
ObjectAnimator.ofFloat(btnShow, "translationX", 0, 1, 0, 1)
.setDuration(3000)
.start();
這是一個屬性動畫最簡單的用法,默認的插值器也是加速減速插值器,具體插值器可以看插值器簡單示例
分析一下ofInt(Object target, String propertyName, int... values)參數(shù):
| 參數(shù) | 解釋 |
|---|---|
| target | 對象,指定要改變誰的屬性 |
| propertyName | 屬性名,指定要改變對象的什么屬性,這個屬性名要求在兌現(xiàn)中必須有對應(yīng)的public的PsetPropertyName的方法。如上面的textColor就要求Button中必須有setTextColor方法才行。 |
| values | 一系列這個屬性將會到達的值。 |
從這里可以看到這個屬性動畫也是名副其實,只要這個對象里設(shè)置有對應(yīng)屬性的set方法,就能用屬性動畫改變這個屬性。
常用的屬性動畫
因為屬性動畫可以改變提供了set方法的任意屬性,所以就不像ViewAnimation一樣僅僅局限于旋轉(zhuǎn),平移,縮放,漸變這四種動畫了。
下面是常用的屬性動畫
| ObjectAnimator第二個參數(shù)的屬性 | 對應(yīng)的set方法 | 效果 |
|---|---|---|
| alpha | public void setAlpha(float alpha) | 改變透明度 |
| translationX | setTranslationX | 沿X軸平移 |
| translationY | setTranslationY | 沿Y軸平移Y |
| scaleX | setScaleX | 沿X軸縮放 |
| scaleY | setScaleY | 沿Y軸縮放 |
| rotationX | setRotationX | 繞X軸旋轉(zhuǎn) |
| rotationY | setRotationY | 繞Y軸旋轉(zhuǎn) |
| rotation | setRotation | 繞Z軸旋轉(zhuǎn) |
旋轉(zhuǎn)
- 繞Z軸旋轉(zhuǎn),Z軸就是垂直于屏幕的那個軸
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(btnShow,"rotation",0,360);
objectAnimator.setDuration(3000);
objectAnimator.start();

- 繞X軸旋轉(zhuǎn)
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(btnShow,"rotationX",0,360);
objectAnimator.setDuration(3000);
objectAnimator.start();

- 繞Y軸旋轉(zhuǎn)
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(btnShow,"rotationY",0,360);
objectAnimator.setDuration(3000);
objectAnimator.start();

透明
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(btnShow,"alpha",0,1,0,1);
objectAnimator.setDuration(3000);
objectAnimator.start();

平移
- 沿X軸平移
ObjectAnimator.ofFloat(btnShow, "translationX",0,200)
.setDuration(3000)
.start();

- 沿Y軸平移
ObjectAnimator.ofFloat(btnShow, "translationY",0,200)
.setDuration(3000)
.start();

縮放
- 沿X軸縮放
ObjectAnimator.ofFloat(btnShow, "scaleX",0,1)
.setDuration(3000)
.start();

- 沿Y軸平移
ObjectAnimator.ofFloat(btnShow, "scaleY",0,1)
.setDuration(3000)
.start();

改變兩個屬性動畫
上面都是一次改變一個屬性的,有沒有錯同事改變兩個屬性的方法呢?
ObjectAnimator提供有對應(yīng)的方法ofFloat (Object target,String xPropertyName,String yPropertyName, Path path).Path定義兩個屬性要經(jīng)過的值。
比如要向右下角平移,要同時改變translationX和translationY。Path的moveTo是定義初始值,默認是(0,0)。lineTo定義經(jīng)過的值。下面是先平移到(500,500),再平移到(300,600):
Path path = new Path();
path.moveTo(0,0);
path.lineTo(500,500);
path.lineTo(300,600);
ObjectAnimator.ofFloat(btnShow,"translationX", "translationY",path)
.setDuration(3000)
.start();

也可以改變連個不一樣的值,比如讓按鈕平移的同時進行放大:
Path path = new Path();
path.moveTo(0,1);
path.lineTo(300,3);
ObjectAnimator.ofFloat(btnShow,"translationX", "scaleY",path)
.setDuration(3000)
.start();

對動畫的監(jiān)聽
ObjectAnimator繼承自ValueAnimator,所以對他的監(jiān)聽方法很ValueAnimator是一樣的,
Android動畫-屬性動畫-ValueAnimato 對動畫過程的控制
XML表示
ObjectAnimator當然也惡意用XML來寫,對應(yīng)的標簽是<objectAnimator> ,以縮放為例:
在res/animator中建立文件anim_obj.xml,這幾個屬性應(yīng)該一看就只帶是什么意思了,基本上所有的動畫這些屬性的意思都是一樣的:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueType="floatType"
android:valueFrom="1"
android:valueTo="3"
android:startOffset="0"
android:duration="2000"
android:interpolator="@android:anim/linear_interpolator"
android:propertyName="scaleY"
android:repeatCount="1"
android:repeatMode="reverse"/>
然后在代碼中調(diào)用:
ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(context,R.animator.anim_obj);
objectAnimator.setTarget(btnShow);
objectAnimator.start();
這里必須調(diào)用setTarget方法,不然動畫的效果看不出來。這個方法告訴動畫要改變誰的屬性值。
