Android 属性动画使用(二)
首先扯點別的:晚上稍微跑了一會步,然后逛了超市,晚飯喝的南瓜粥,吃了一碗面條,今天不是太餓,現在正一邊吃著葡萄一邊學習,也是沒誰了。
比如說,我們想要實現從0過渡到100,使用ValueAnimator 就可以這樣寫:
ValueAnimator va = ValueAnimator.ofInt(1, 00); va.setDuration(3000); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {Log.e("tag", "value : " + animation.getAnimatedValue());} }); va.start();打印出來的結果就是從1到100;但是這是怎么實現的呢,這是因為系統內置了一個IntEvaluator(相當于一個計算器)來實現計算如何從動畫的初始值過渡到結束值。
//IntEvaluator 的evaluate方法 public Integer evaluate(float fraction, Integer startValue, Integer endValue) {int startInt = startValue;//就返回初始值加上fraction乘上結束值減去初始值fraction變化范圍0到1return (int)(startInt + fraction * (endValue - startInt)); }ValueAnimator有一個ofObject方法,用來操作對象的動畫。但是和ofInt或者ofFloat方法相比,ofObject沒法內置一個Evaluator,因為對象不同,計算的方式也不一樣,所以要自己實現一個繼承自TypeEvaluator的Evaluator。
使用場景:自定義一個View,View中有一個Point()對象用來管理坐標,View在onDraw方法中根據Point()對象的坐標進行繪制,然后使用ValueAnimator來改變Poin對象的坐標值,那么自定義View就會實現動畫效果。
//具有x,y兩個屬性和相應的get,set函數 public class MyPoint {private float x;private float y;public MyPoint(float x, float y) {this.x = x;this.y = y;}public float getX() {return x;}public float getY() {return y;} }自定義PointEvaluator
public class PointEvaluator implements TypeEvaluator<MyPoint> {@Overridepublic MyPoint evaluate(float fraction, MyPoint startValue, MyPoint endValue) {//改變x值float x = startValue.getX() + fraction * (endValue.getX() - startValue.getX());//改變y值float y = startValue.getY() + fraction * (endValue.getY() - startValue.getY());MyPoint point = new MyPoint(x, y);//返回一個新的Point對象,坐標已經改變了return point;} }新建一個PointAnimView 繼承自View
public class PointAnimView extends View {public static final float RADIUS = 50f; //point點的半徑private MyPoint currentPoint;private Paint mPaint;public PointAnimView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.BLUE);}@Overrideprotected void onDraw(Canvas canvas) {//第一次繪制初始的點之后就啟動動畫if (currentPoint == null) {currentPoint = new MyPoint(RADIUS, RADIUS);drawCircle(canvas);startAnimation();} else {drawCircle(canvas);}}private void drawCircle(Canvas canvas) {float x = currentPoint.getX();float y = currentPoint.getY();canvas.drawCircle(x, y, RADIUS, mPaint);}private void startAnimation() {MyPoint startPoint = new MyPoint(RADIUS, RADIUS);MyPoint endPoint = new MyPoint(getWidth() - RADIUS, getHeight() - RADIUS);ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {currentPoint = (MyPoint) animation.getAnimatedValue();invalidate(); }});anim.setDuration(5000);anim.start();} }將PointAnimView 引入布局文件使用。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.hm.animationdemo.widget.PointAnimViewandroid:id="@+id/point_view"android:layout_width="match_parent"android:layout_height="match_parent" /> </RelativeLayout>效果圖
ObjectAnimator的高級用法
實現動態改變PointAnimView的顏色,那就得給PointAnimView添加color屬性并提供相應的getColor方法和setColor方法,在setColor方法中改變View里面畫筆的顏色,然后調用invalidate方法刷新視圖,在繪制的時候,View的顏色就會發生變化
private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; mPaint.setColor(Color.parseColor(color)); invalidate(); }ObjectAnimator的ofObject方法
//可以看到第三個參數是一個TypeEvaluator ,用來計算Object的屬性,在這里就是我們的color如何變化, //所以要重寫一個TypeEvaluator來計算顏色的變化 public static ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values) //這個實現細節,就愉快的略過吧。 public class ColorEvaluator implements TypeEvaluator { private int mCurrentRed = -1; private int mCurrentGreen = -1; private int mCurrentBlue = -1; @Override public Object evaluate(float fraction, Object startValue, Object endValue) { String startColor = (String) startValue; String endColor = (String) endValue; int startRed = Integer.parseInt(startColor.substring(1, 3), 16); int startGreen = Integer.parseInt(startColor.substring(3, 5), 16); int startBlue = Integer.parseInt(startColor.substring(5, 7), 16); int endRed = Integer.parseInt(endColor.substring(1, 3), 16); int endGreen = Integer.parseInt(endColor.substring(3, 5), 16); int endBlue = Integer.parseInt(endColor.substring(5, 7), 16); // 初始化顏色的值 if (mCurrentRed == -1) { mCurrentRed = startRed; } if (mCurrentGreen == -1) { mCurrentGreen = startGreen; } if (mCurrentBlue == -1) { mCurrentBlue = startBlue; } // 計算初始顏色和結束顏色之間的差值 int redDiff = Math.abs(startRed - endRed); int greenDiff = Math.abs(startGreen - endGreen); int blueDiff = Math.abs(startBlue - endBlue); int colorDiff = redDiff + greenDiff + blueDiff; if (mCurrentRed != endRed) { mCurrentRed = getCurrentColor(startRed, endRed, colorDiff, 0, fraction); } else if (mCurrentGreen != endGreen) { mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff, redDiff, fraction); } else if (mCurrentBlue != endBlue) { mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff, redDiff + greenDiff, fraction); } // 將計算出的當前顏色的值組裝返回 String currentColor = "#" + getHexString(mCurrentRed) + getHexString(mCurrentGreen) + getHexString(mCurrentBlue); return currentColor; } /** * 根據fraction值來計算當前的顏色。 */ private int getCurrentColor(int startColor, int endColor, int colorDiff, int offset, float fraction) { int currentColor; if (startColor > endColor) { currentColor = (int) (startColor - (fraction * colorDiff - offset)); if (currentColor < endColor) { currentColor = endColor; } } else { currentColor = (int) (startColor + (fraction * colorDiff - offset)); if (currentColor > endColor) { currentColor = endColor; } } return currentColor; } /** * 將10進制顏色值轉換成16進制。 */ private String getHexString(int value) { String hexString = Integer.toHexString(value); if (hexString.length() == 1) { hexString = "0" + hexString; } return hexString; } }定義好了ColorEvaluator ,就可以改變顏色了,改變MyAinmView中的startAnimation方法,就可以實現在改變view的位置的同時改變view的顏色了。
private void startAnimation() {MyPoint startPoint = new MyPoint(RADIUS, RADIUS);MyPoint endPoint = new MyPoint(getWidth() - RADIUS, getHeight() - RADIUS);ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {currentPoint = (MyPoint) animation.getAnimatedValue();invalidate();}});ObjectAnimator anim2 = ObjectAnimator.ofObject(this, "color", new ColorEvaluator(),"#0000FF", "#FF0000");AnimatorSet animSet = new AnimatorSet();animSet.play(anim).with(anim2);animSet.setDuration(5000);animSet.start(); }效果如下
結尾:文章中的代碼來自部分摘自郭霖老師的博客。是時候睡覺了。
- Android屬性動畫完全解析(中),ValueAnimator和ObjectAnimator的高級用法
總結
以上是生活随笔為你收集整理的Android 属性动画使用(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在家登录学校图书馆知网
- 下一篇: android sina oauth2.