Android:屬性動畫詳解

來源:互聯網
上載者:User

Android:屬性動畫詳解

(一)簡介

屬性動畫是Android 3.0中提供了新功能,便於對任意元素進行“平滑的過渡”。眾所周知,Android 之前提供的補間動畫如AlphaAnimation、TranslateAnimation等都只能應用在View上,並且幾乎沒有任何可擴充的地方。並且,使用原來的動畫無法實現色彩坡形效果,算是一個遺憾。

屬性動畫徹底打破了這種設計方式,不再將這些動畫強制的放在View上,而是僅僅產生一系列的值,由開發人員自行使用這些值。例如,屬性動畫可產生1~0平滑過渡的值,把這些值應用在View的alpha上就可以實現透明度漸層了。

同時,屬性動畫可以直接用來改變View的屬性。例如,不斷的setTranslationX,便可實現水平方向的平移。

(二)代碼示範

1.ValueAnimator:產生某個範圍內平滑過渡的值。

 

//屬性動畫,0~1漸層    public void simpleValueAnimator(View view) {        ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);        anim.setDuration(300);        //動畫過程的監聽        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                //回調方法在主線程執行                float currentValue = (float) animation.getAnimatedValue();                Log.d(TAG, "current value is " + currentValue);            }        });        anim.start();    }
(1)該方法可以通過設定多個值來實現更複雜的“平滑過渡”,例如實現0~5~3~10的過渡效果:
ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f);
(2)設定啟動延時、重複次數、重複模式:

 

 

//設定啟動延時        anim.setStartDelay(1000);        //設定重複次數(也可以設定成無限次數)        anim.setRepeatCount(3);        //設定重複模式:重新執行動畫(也可以設定成倒序)        anim.setRepeatMode(ValueAnimator.RESTART);
(3)監聽動畫開始、結束、重複狀態:

 

 

//監聽動畫的狀態(開始/結束/重複/取消)        anim.addListener(new AnimatorListenerAdapter() {            @Override            public void onAnimationStart(Animator animation) {                super.onAnimationStart(animation);                Log.d(TAG, "onAnimationStart");            }            @Override            public void onAnimationRepeat(Animator animation) {                super.onAnimationRepeat(animation);                Log.d(TAG, "onAnimationRepeat");            }            @Override            public void onAnimationEnd(Animator animation) {                super.onAnimationEnd(animation);                Log.d(TAG, "onAnimationEnd");            }        });
2.ObjectAnimator:平滑的改變任意對象的屬性值。

 

(1)平滑改變TextView的不透明度:

 

public void changeAlphaValue(View view) {        TextView textView = (TextView) findViewById(R.id.main_text1);        //ObjectAnimator繼承自ValueAnimator        //animator會調用textView的setAlpha方法。如果該方法不存在則會出現警告異常。        ObjectAnimator animator = ObjectAnimator.ofFloat(textView, "alpha", 1f, 0f, 1f);        animator.setDuration(3000);        animator.start();    }
該動畫並非直接改變textView的alpha屬性(事實上,textView甚至它的父組件View都沒有alpha屬性),而是調用textView的setAlpha方法,然後傳入1~0~1平滑漸層的值作為參數,從而實現了不透明度漸層效果。

 

類似的,可以通過傳遞參數rotation、translationX(translationY)等實現旋轉、平移等效果。

3.使用AnimatorSet將各個動畫進行組合:

 

public void animatorSet(View view) {        TextView textView = (TextView) findViewById(R.id.main_text1);        ObjectAnimator moveIn = ObjectAnimator.ofFloat(textView, "translationX", -500f, 0f);        ObjectAnimator rotate = ObjectAnimator.ofFloat(textView, "rotation", 0f, 360f);        ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textView, "alpha", 1f, 0.2f, 1f);        //先平移,然後在旋轉的同時進行alpha漸層        AnimatorSet animSet = new AnimatorSet();        animSet.play(rotate).with(fadeInOut).after(moveIn);        animSet.setDuration(5000);        animSet.start();    }
animSet.play會產生一個Animator.Builder對象,然後可以使用with,after,before等方法進行動畫疊加。

 

4.自訂Evaluator,實現任意兩個對象之間的“平滑過渡”。

ValueAnimator的ofInt,ofFloat方法很簡單,無非是產生一些平滑過渡的數值。不過,ValueAnimator還有一個ofObject方法,可以實現兩個Object之間的平滑過渡。顯然,系統不可能知道應該怎麼過渡,因此需要我們指定它。

例如定義了一個類表示點的座標:

 

public class PointBean {    private float x;    private float y;    public PointBean(float x, float y) {        this.x = x;        this.y = y;    }    public float getX() {        return x;    }    public void setX(float x) {        this.x = x;    }    public float getY() {        return y;    }    public void setY(float y) {        this.y = y;    }}
然後,我們希望實現兩個點之間的平滑過渡(通過它就可以實現View的平移了),就需要定義兩個PointBean之間是如何過渡的。當然此處的實現很簡單:

 

 

public class PointEvaluator implements TypeEvaluator {    @Override    public PointBean evaluate(float fraction, PointBean startValue, PointBean endValue) {        float x = startValue.getX() + fraction * (endValue.getX() - startValue.getX());        float y = startValue.getY() + fraction * (endValue.getY() - startValue.getY());        return new PointBean(x, y);    }}
參數fraction表示動畫完成度(0.0~1.0的一個值),startValue表示開始點,endValue表示結束點,該方法需要返回從startValue過渡到endValue、完成比例是fraction時的結果。
然後,通過兩個PointBean的過渡實現平移效果(此處僅為示意,實際情境中可以直接使用ObjectAnimator):

 

 

ValueAnimator animator = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);        animator.setDuration(2000);        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                PointBean current = (PointBean) animation.getAnimatedValue();                imageView.setTranslationX(current.getX());                imageView.setTranslationY(current.getY());            }        });        animator.start();
5.實現色彩坡形

 

與上述內容相似,實現紅色~綠色~藍色的漸層:

 

ValueAnimator animator = ValueAnimator.ofObject(new ColorEvaluator(), "#ffff0000", "#ff00ff00", "#ff0000ff");        animator.setDuration(5000);        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                String currentColor = (String) animation.getAnimatedValue();                textView.setBackgroundColor(Color.parseColor(currentColor));            }        });        animator.start();
顯然此處的重點是ColorEvaluator,即指定顏色值是如何漸層的。例如, #ffff0000是如何過渡到#ff00ff00的。
public class ColorEvaluator implements TypeEvaluator {    //僅支援AARRGGBB模式    @Override    public String evaluate(float fraction, String startValue, String endValue) {        if (!startValue.startsWith("#") || !endValue.startsWith("#")) {            throw new IllegalArgumentException("color must started with '#'.");        }        if (startValue.length() != 9 || endValue.length() != 9) {            throw new IllegalArgumentException("startValue and endValue must be '#AARRGGBB'.");        }        int start_a, start_r, start_g, start_b;        int end_a, end_r, end_g, end_b;        //start        start_a = getIntValue(startValue, 1, 3);        start_r = getIntValue(startValue, 3, 5);        start_g = getIntValue(startValue, 5, 7);        start_b = getIntValue(startValue, 7, 9);        //end        end_a = getIntValue(endValue, 1, 3);        end_r = getIntValue(endValue, 3, 5);        end_g = getIntValue(endValue, 5, 7);        end_b = getIntValue(endValue, 7, 9);        return "#" + getHexString((int) (start_a + fraction * (end_a - start_a)))                + getHexString((int) (start_r + fraction * (end_r - start_r)))                + getHexString((int) (start_g + fraction * (end_g - start_g)))                + getHexString((int) (start_b + fraction * (end_b - start_b)));    }    //從原始#AARRGGBB顏色值中指定位置截取,並轉為int.    private int getIntValue(String hexValue, int start, int end) {        return Integer.parseInt(hexValue.substring(start, end), 16);    }    private String getHexString(int value) {        String a = Integer.toHexString(value);        if (a.length() == 1) {            a = "0" + a;        }        return a;    }}
6.設定Interpolator,控制動畫進行的方式,如勻速、逐漸加速、逐漸減速或先加速後減速等效果。此處和傳統的動畫很相似。同樣,可以自訂Interpolator的實現。

 

 

anim.setInterpolator(new AccelerateInterpolator());  //逐漸加速的動畫
7.ViewPropertyAnimator:使用屬性動畫為View設定動畫效果的一種簡便方式。

 

 

testImageView.animate().setDuration(2000).alpha(0.3f).rotationBy(360).yBy(160);
上述代碼錶示將testImageView的不透明度漸層至0.3,同時旋轉360度、向下移動160px。

 

這裡的方法都有兩種形式,如rotation(360)表示旋轉至360度的位置(不管起始狀態是多少度,都旋轉至360度),而rotationBy(360)表示旋轉360度(如果起始位置不是0度,則結束時依然不是0度)。






 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.