編輯:關於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了,還是很容易的。
轉載請注明出處:http://blog.csdn.net/droyon/article/details/29830157 本文以Android內核剖析為基准,結合and
Matrix的數學原理在Android中,如果你用Matrix進行過圖像處理,那麼一定知道Matrix這個類。Android中的Matrix是一個3 x 3的矩陣,其內容
介紹 在谷歌的官網我們可以看到它是這樣介紹的:RecyclerView is a more advanced and flexible version of List
1、廣播機制簡介Android中的每個應用程序都可以對自己感興趣的廣播進行注冊,這樣該程序就只會接收到自己所關心的廣播內容,這些廣播可能是來自於系統的,也可能是來自於其他
前言:在上篇中,分析了MediaPlayer的從創建到setDataSo