編輯:關於Android編程
ObjectAnimator,通過設置改變對象的屬性來實現動畫效果,常用的方法有這麼幾種,ofFloat()、ofInt()、ofObject()、ofArgb()、ofPropertyValuesHolder(),具體含義及使用我們在下面的實例中進行講解。
一、動畫類型使用ObjectAnimator也是可以輕松的實現平移、縮放、旋轉、透明度這幾種動畫效果的,與補間動畫的使用效果是一樣的,那就先來看看這幾種常用的動畫是怎麼實現的。
工程代碼裡就是一個ImageView控件和Activity,
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_object_animator);
head = (ImageView) findViewById(R.id.head);
}
我們這裡就是對ImageView控件head實現動畫效果,本質就是改變head的屬性。
1.平移(translate)
// 平移 private void translateAnimation() { ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(head, "translationX", 0.0f, 350.0f, 0.0f); objectAnimator.setDuration(2000); objectAnimator.setRepeatCount(Animation.INFINITE); objectAnimator.setRepeatMode(Animation.RESTART); objectAnimator.start(); }
這段代碼就是用來實現控件的平移,我們來逐行分析這段代碼。
ofFloat方法的函數原型,
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
參數含義:
target:動畫操作的對象,我們這裡的操作對象就是ImageView控件head
propertyName:屬性名稱,這裡的"translationX"屬性值意思就是在水平方向移動,如果是"translationY"就是在垂直方向移動,下面講到的其動畫效果也是這個意思,這個屬性值跟我們在xml文件中設置屬性值得名稱是一致的,比如
"android:translationY"。
values:動畫過渡值,過渡值可以有一個到N個,如果是一個值的話,就默認是這個動畫過渡值的結束值,如果有N個值,動畫就在這N個值之間過渡,如本例中有三個過渡值"0.0f, 350.0f, 0f",意思就是從當前位置向右滑到350的位置,再滑到位置0,即初始位置。
然後是動畫的設置,
objectAnimator.setDuration(2000);//動畫的時間間隔
objectAnimator.setRepeatCount(Animation.INFINITE);//重復次數
objectAnimator.setRepeatMode(Animation.RESTART);//重復模式
最後start,動畫就開始執行了
objectAnimator.start();
2.縮放(scale)
// 縮放
private void scaleXAnimation() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(head, "scaleX", 1.0f, 1.5f);
objectAnimator.setDuration(2000);
objectAnimator.setRepeatCount(Animation.INFINITE);
objectAnimator.setRepeatMode(Animation.RESTART);
objectAnimator.start();
}

3.旋轉(rotate)
// 旋轉
private void rotateAnimation() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(head, "rotationX", 0.0f, 90.0f,0.0F);
objectAnimator.setDuration(2000);
objectAnimator.setRepeatCount(Animation.INFINITE);
objectAnimator.setRepeatMode(Animation.RESTART);
objectAnimator.start();
}

4.透明度(alpha)
// 透明度
private void alphaAnimation() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(head, "alpha", 1.0f, 0.3f, 1.0F);
objectAnimator.setDuration(2000);
objectAnimator.setRepeatCount(Animation.INFINITE);
objectAnimator.setRepeatMode(Animation.RESTART);
objectAnimator.start();
}

可能我們也注意到了,在縮放效果的實例中,圖片被放大後就保持當前的狀態,沒有變為初始的樣子,這是因為我們在設置過渡值是最終的狀態是1.5f,就放大到1.5倍,並沒有讓它回到原來的狀態,從這點就可以看出,屬性動畫是真真切切的可以改變控件的屬性的,這是與補間動畫的最大不同,補間動畫在動畫結束後都將回到初始狀態。所以說,屬性動畫的使用就顯得更加的靈活。至於上面的其他三個實例,最終回到初始狀態,是因為我們在設過渡值的時候最終狀態設定的就是初始狀態。
剛才我們討論了幾種常見的動畫效果,如果僅有這些功能的話,那就與補間動畫沒有太大的區別。其實,屬性動畫還可以設置其他的屬性值。ObjectAnimator的ofObject方法,就是用來對任意對象進行動畫設置的,如字體顏色,直接看實例
int startColor = 0xffff0000;
int endColor = 0xff00ff00;
ObjectAnimator objectAnimator4 = ObjectAnimator.ofObject(txt, "textColor", new TypeEvaluator() {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
(int)((startR + (int)(fraction * (endR - startR))) << 16) |
(int)((startG + (int)(fraction * (endG - startG))) << 8) |
(int)((startB + (int)(fraction * (endB - startB))));
}
}, startColor, endColor);
objectAnimator4.setDuration(3000);
objectAnimator4.start();

ofObject方法的原型
public static ObjectAnimator ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values)我們看到它比ofFloat多了一個TypeEvaluator參數,它是用來告知系統如何進行屬性值過渡的,由於ofObject是任意屬性,所以需要自己實現TypeEvaluator,ofFloat沒有該參數是因為系統默認實現了其過渡行為FloatEvaluator,關於TypeEvaluator我們會單獨講解,這邊就不在詳述了。 除了字體顏色外,還可以設置背景色"backgroundColor"等。 剛才的字體顏色除了使用ofObject方法外,還可以使用ofArgb,但需要SDK版本21上支持,目前市面上很多機型還是21以下的,暫時我們最好不要使用。
ObjectAnimator objectAnimator2 = ObjectAnimator.ofArgb(txt, "textColor", 0x000, 0x00FF00); objectAnimator2.start();
1.setInterpolator():設置動畫插值
控制動畫的變化速率,系統中定義了好幾種Interpolator:
LinearInterpolator--均勻的速率改變AccelerateDecelerateInterpolator--先加速後減速
AccelerateInterpolator--加速
DecelerateInterpolator--減速
CycleInterpolator--動畫循環播放特定的次數,速率改變沿著正弦曲線 2.setDuration():設置動畫執行時間,動畫時間以毫秒為單位(ms)3.setRepeatCount():設置動畫重復次數
大於0的值就代表重復幾次,如果需要無限循環,設為-1,上面的Animation.INFINITE是系統給的常量,值為-1,代表無限循環,我們建議使用這個常量,如果設為0呢?也是執行一次。
4.setRepeatMode():設置動畫重復模式
5.setStartDelay():設置動畫延時操作,也是以毫秒為單位(ms)
6.setTarget():設置動畫的對象
操作對象,上面的例子中將動畫對象通過ofXXX方傳遞,如果需要改變動畫對象,但動畫效果不變,我們可以使用該方法來設置。
objectAnimator.setTarget(txt);//將動畫對象head變為txt7.setEvaluator():設置動畫過度的評估者,即設置TypeEvaluator對象,後面會詳細介紹 三、組合動畫 上面講到的都是單一的動畫,在實際使用時,有可能同時需要多種動畫效果,比如同時在水平方向和垂直方向進行縮放並且同時繞水平方向旋轉,要實現這樣的效果就必須用到組合動畫。可以有三種方式來實現,一一講解。 1.AnimatorSet AnimatorSet可以讓幾個動畫同時執行,也可以設置執行順序、延遲執行等,
after(Animator anim)--將現有動畫插入到傳入的動畫之後執行
after(long delay)--將現有動畫延遲指定毫秒後執行
before(Animator anim)--將現有動畫插入到傳入的動畫之前執行
with(Animator anim)--將現有動畫和傳入的動畫同時執行
playSequentially(Animator... items)--依次執行
private void multiAnimation() {
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(head, "scaleX", 1.0f, 2.5f, 1.0f);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(head, "scaleY", 1.0f, 2.5f, 1.0f);
ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(head, "rotationX", 0.0f, 90.0f,0.0F);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(objectAnimator1).with(objectAnimator2).with(objectAnimator3);
animatorSet.setDuration(2000);
animatorSet.start();
}

讓動畫同時執行除了使用with方法外,還可以用playTogether方法,
animatorSet.playTogether(objectAnimator1, objectAnimator2, objectAnimator3);其他幾種就不在演示了。 2.PropertyValuesHolder
這種方式只能多個動畫一起執行,不同設置先後順序。
private void multiAnimation2() {
PropertyValuesHolder valuesHolder = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 2.5f, 1.0f);
PropertyValuesHolder valuesHolder1 = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 2.5f, 1.0f);
PropertyValuesHolder valuesHolder2 = PropertyValuesHolder.ofFloat("rotationX", 0.0f, 90.0f,0.0F);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(head, valuesHolder, valuesHolder1, valuesHolder2);
objectAnimator.setDuration(2000);
objectAnimator.start();
}
3.ViewPropertyAnimator
該類是多屬性動畫,從名字就可以看出該類的作用對象是view,當一個view對象需要同時執行多個屬性動畫的時候就可以考慮使用該類了。比如說:一個ImageView先右移動的同時進行放大一倍的動畫效果實現如下
private void viewPropertyAnimator() {
ViewPropertyAnimator animator = head.animate();
animator.translationX(200)
.scaleX(2)
.scaleY(2)
.setDuration(2000)
.start();
}
一般情況下,我們除了需要動畫效果外,還需要對動畫的執行過程進行監聽,在執行前、執行結束後或者執行過程中,做出相應的處理,比如動畫結束後,請求網絡數據。系統給我們提供幾種監聽接口,來監聽動畫的各個狀態,如AnimatorListener,
private void animationListener() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(head, "translationX", 0.0f, 350.0f, 0f);
objectAnimator.setDuration(2000);
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Log.d("dingfeng", "onAnimationStart......");
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d("dingfeng", "onAnimationEnd......");
}
@Override
public void onAnimationCancel(Animator animation) {
Log.d("dingfeng", "onAnimationCancel......");
}
@Override
public void onAnimationRepeat(Animator animation) {
Log.d("dingfeng", "onAnimationRepeat......");
}
});
objectAnimator.start();
}
可以根據不同需求來實現接口裡面的四個方法,可以根據需要做相應的處理。但有時候你會覺得我不需要監聽動畫的四種狀態,我只需要監聽動畫結束時候的狀態,使用上面的方法就會感覺代碼臃腫了,不過沒關系,Android系統給我們提供了一個更好用的方法,
private void animationListener2() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(head, "translationX", 0.0f, 350.0f, 0f);
objectAnimator.setDuration(2000);
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Log.d("dingfeng", "onAnimationEnd......");
}
});
objectAnimator.start();
}
可以看出,我們使用了AnimatorListenerAdapter動畫接口適配器代替AnimatorListener接口。其實AnimatorListenerAdapter的源碼只是一個實現了AnimatorListener接口的抽象類而已,
你需要監聽哪種動畫狀態就重寫哪種方法就可以了。
除此之外,AnimatorUpdateListener接口就可以讀取到動畫的每個更新值。
private void animationListener3() { ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(head, "translationX", 0.0f, 350.0f, 0f); objectAnimator.setDuration(2000); objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float value = (float)animation.getAnimatedValue(); Log.d("dingfeng", "onAnimationUpdate......"+value); } }); objectAnimator.start(); }
一般情況下不太用到這個接口,但是在自定義動畫的時候,通過該接口,可以實現很多復雜的效果。
五、xml編寫動畫
當然,我們也可以在xml文件中配置動畫,這樣做可以比較好的復用這些動畫,減少代碼量。
1.在資源目錄下創建animator文件夾
將編寫的xml文件放在該目錄下,如下圖

我們創建兩個動畫文件,一個是旋轉動畫,一個組合動畫
2.加載動畫 使用AnimatorInflater加載動畫文件
head = (ImageView) findViewById(R.id.head); Animator animator = AnimatorInflater.loadAnimator(this, R.animator.multi); animator.setTarget(head); animator.start();這樣就OK了,還是很容易的。
andriod中Context理解總結
轉載請注明出處:http://blog.csdn.net/droyon/article/details/29830157 本文以Android內核剖析為基准,結合and
Android Matrix源碼詳解
Matrix的數學原理在Android中,如果你用Matrix進行過圖像處理,那麼一定知道Matrix這個類。Android中的Matrix是一個3 x 3的矩陣,其內容
android L新控件RecyclerView詳解與DeMo
介紹 在谷歌的官網我們可以看到它是這樣介紹的:RecyclerView is a more advanced and flexible version of List
第5章 全局大喇叭,詳解廣播機制
1、廣播機制簡介Android中的每個應用程序都可以對自己感興趣的廣播進行注冊,這樣該程序就只會接收到自己所關心的廣播內容,這些廣播可能是來自於系統的,也可能是來自於其他
Android Multimedia框架總結(四)MediaPlayer中從Java層到C++層類關系及prepare及之後其他過程
前言:在上篇中,分析了MediaPlayer的從創建到setDataSo