Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 屬性動畫學習(一)--Animator類+ValueAnimator類源碼解析

屬性動畫學習(一)--Animator類+ValueAnimator類源碼解析

編輯:關於Android編程

ValueAnimator:對值進行平滑的動畫過渡。繼承Animator抽象類

ObjectAnimator:對任意對象的任意屬性進行動畫操作。繼承自ValueAnimator

1、Animator源碼解析

給所有動畫提供基本支持類,是一個抽象類

啟動動畫。如果startDelay的值非零,動畫會在延時過後開始。如果沒有設置延時值,則會馬上啟動動畫。動畫在調用該方法的線程上運行。

 public void start() {
    }

取消動畫。和end()不一樣,取消動畫是停止在其運行軌道上,並回調給android.animation.Animator.AnimatorListener#onAnimationCancel(Animator)。此方法必須在運行動畫的線程調用。

 public void cancel() {
    }

結束動畫。結束動畫後,調用的動畫屬性會有最終值。此方法必須在運行動畫的線程調用。
public void end() {
    }

暫停正在運行的動畫。此方法調用的線程必須和動畫開始的線程在同一個線程中。如果動畫的狀態不是正在運行的,調用該方法無效。

 

public void pause() {
        if (isStarted() && !mPaused) {//動畫正在運行並且暫停狀態是false
            mPaused = true;
            if (mPauseListeners != null) {
                ArrayList tmpListeners =
                        (ArrayList) mPauseListeners.clone();
                int numListeners = tmpListeners.size();
                for (int i = 0; i < numListeners; ++i) {
                    tmpListeners.get(i).onAnimationPause(this);
                }
            }
        }
    }

 

 

重啟暫停的動畫。調用該方法的線程必須和動畫開始的線程是同一個。調用該方法並且有效的前提是pause()生效之後的調用。
 public void resume() {
        if (mPaused) {
            mPaused = false;
            if (mPauseListeners != null) {
                ArrayList tmpListeners =
                        (ArrayList) mPauseListeners.clone();
                int numListeners = tmpListeners.size();
                for (int i = 0; i < numListeners; ++i) {
                    tmpListeners.get(i).onAnimationResume(this);
                }
            }
        }
    }

返回當前動畫是否是暫停狀態。true:暫停狀態。false:非暫停狀態。

 

public boolean isPaused() {
        return mPaused;
    }

返回延遲動畫運行的時間,毫秒數。抽象方法,無方法體,具體實現在其子類中。

 

 

public abstract long getStartDelay();

設置延遲動畫運行的時間。毫秒數。

 

 

public abstract void setStartDelay(long startDelay);

設置動畫運行時間。毫秒數。

 

 

public abstract Animator setDuration(long duration);

獲得動畫運行時間。毫秒數。

 

 

 public abstract long getDuration();

設置動畫效果。TimeInterpolator:控制動畫的變化速率,且這個變化速率是非線性的,如加速、減速、重復、彈跳等。TimeInterpolator是屬性動畫中新增的接口,用於兼容補間動畫中的Interpolator接口。

AccelerateDecelerateInterpolator 在動畫開始與結束的地方速率改變比較慢,在中間的時候加速

AccelerateInterpolator 在動畫開始的地方速率改變比較慢,然後開始加速

AnticipateInterpolator 開始的時候向後然後向前甩

AnticipateOvershootInterpolator 開始的時候向後然後向前甩一定值後返回最後的值

BounceInterpolator 動畫結束的時候彈起

CycleInterpolator 動畫循環播放特定的次數,速率改變沿著正弦曲線

DecelerateInterpolator 在動畫開始的地方快然後慢

LinearInterpolator 以常量速率改變

OvershootInterpolator 向前甩一定值後再回到原來位置

也可以自定義。

public abstract void setInterpolator(TimeInterpolator value);

獲取當前運行的動畫的變化率,如果直接get獲取,得到的是null,因為Animatior中沒有實現TimeInterpolator接口。注意:TimeInterpolator是一個接口類。

public TimeInterpolator getInterpolator() {
        return null;
    }
當前動畫是否正在運行。true:正在運行。false:有可能停止或暫停或未開始。
public abstract boolean isRunning();

當前動畫是否開始運行並且運行還未結束。實際上返回的是isRunning()的值,因為如果設置了延遲,延遲時間還未結束,動畫還未進行,isStarted()會返回true。但是在延遲時間內,動畫還沒有開始,isRunning()的值只會在延遲結束後返回true,只有當動畫真正運行了,才會返回true。所以isStarted()實際調用isRunning()更准確。

public boolean isStarted() {
        // Default method returns value for isRunning(). Subclasses should override to return a
        // real value.
        return isRunning();
    }

給當前動畫添加監聽器,或者說是接收一個監聽器,只要實現listener監聽器的方法就可以實現對動畫的各種監聽了。

ArrayList mListeners = null; // start,end,cancel,repeat回調
ArrayList mPauseListeners = null; // pause, resume回調
ArrayList mUpdateListeners = null; // value更新回調

public void addListener(AnimatorListener listener) {
        if (mListeners == null) {
            mListeners = new ArrayList();
        }
        mListeners.add(listener);//添加到監聽組中
    }

從當前動畫的監聽組中移除指定動畫監聽器。

public void removeListener(AnimatorListener listener) {
        if (mListeners == null) {
            return;
        }
        mListeners.remove(listener);
        if (mListeners.size() == 0) {
            mListeners = null;
        }
    }

獲得當前動畫的所有監聽器。
public ArrayList getListeners() {
        return mListeners;
    }
給當前動畫添加暫停監聽器。
public void addPauseListener(AnimatorPauseListener listener) {
        if (mPauseListeners == null) {
            mPauseListeners = new ArrayList();
        }
        mPauseListeners.add(listener);
    }

從當前動畫的暫停監聽器組中移除指定暫停監聽器。
public void removePauseListener(AnimatorPauseListener listener) {
        if (mPauseListeners == null) {
            return;
        }
        mPauseListeners.remove(listener);
        if (mPauseListeners.size() == 0) {
            mPauseListeners = null;
        }
    }

移除當前動畫所有監聽器。就是清空當前動畫的監聽器組合暫停監聽器組。
public void removeAllListeners() {
        if (mListeners != null) {
            mListeners.clear();
            mListeners = null;
        }
        if (mPauseListeners != null) {
            mPauseListeners.clear();
            mPauseListeners = null;
        }
    }

2、ValueAnimator類

使用時間循環機制計算值與值之間的動畫過渡。同時負責管理動畫的播放次數、播放模式、對動畫設置監聽等。運行在一個自定義的handler上,以確保動畫的屬性的改變是運行在UI線程上。動畫的實現可以直接用代碼實現和用xml文件實現。xml文件實現動畫可以大限度實現復用性。

內部變量mPlayingState可能值,以表示動畫當前的狀態。

static final int STOPPED    = 0; // Not yet playing
    static final int RUNNING    = 1; // Playing normally
    static final int SEEKED     = 2; // Seeked to some time value
默認的動畫效果。在動畫開始的時候加速後減速
private static final TimeInterpolator sDefaultInterpolator =
            new AccelerateDecelerateInterpolator();

構造函數。創建ValueAnimator對象。
public ValueAnimator() {
    }

構造並返回一個int類型的動畫的ValueAnimator。一般創建一個對象都是構造函數。顯示創建一個ValueAnimator對象,可以使用比如:ValueAnimator anim= ValueAnimator.ofInt(0,2);。因為ofInt方法內部調用了空構造函數。ValueAnimator是計算值與值之間的平滑過渡動畫,所以通常會傳入兩個及以上的值,不會是單一參數。

如果只有一個值,則作為動畫的終點值,如果有兩個值,則作為動畫的開始值和終點值,如果有兩個以上的,就作為開始值,中間值,終點值,且分布在動畫的過程中。

public static ValueAnimator ofInt(int... values) {
        ValueAnimator anim = new ValueAnimator();
        anim.setIntValues(values);
        return anim;
    }

顏色值之間的過渡動畫。
public static ValueAnimator ofArgb(int... values) {
        ValueAnimator anim = new ValueAnimator();
        anim.setIntValues(values);
        anim.setEvaluator(ArgbEvaluator.getInstance());
        return anim;
    }

float值之間的平滑過渡動畫。傳入參數一般是兩個及以上。ValueAnimator anim = ValueAnimator.ofFloat(0f,1f,0f);
public static ValueAnimator ofFloat(float... values) {
        ValueAnimator anim = new ValueAnimator();
        anim.setFloatValues(values);
        return anim;
    }
屬性值之間的平滑過渡動畫。或者說是PropertyValuesHolder對象之間過渡的動畫。PropertyValuesHolder是一個跟屬性有關的類。
public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) {
        ValueAnimator anim = new ValueAnimator();
        anim.setValues(values);
        return anim;
    }

Object值之間過渡的平滑動畫或者說對任意對象進行動畫操作。TypeEvaluator是一個估值器/評估器/求值器,Android提供了幾個基本估值器,可以通過實現TypeEvaluator接口自定義估值器。根據給定的開始值x0、結束值x1和比例值t返回一個線性插值。計算規則result = x0 + t * (x1 - x0)。比例值t或者說fraction根據動畫已進行時間和總時間計算出的一個時間因子(0~1),即動畫的完成度,是自動計算得到的。x0:動畫的初始值。x1:動畫的結束值。ValueAnimator就是計算動畫的開始值到結束值的一個過渡。 Android提供了以下幾個簡單的Evalutor實現類 IntEvaluator:屬性的值類型為int;即x0和x1的類型是int FloatEvaluator:屬性的值類型為float;即x0和x1的類型是float ArgbEvaluator:屬性的值類型為十六進制顏色值;即x0和x1的類型是argb 除開上面三種估值器類型,對於自定義對象,系統並不知道如何從初始對象過渡到結束對象,所以要自定義估值器類型。
 public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
        ValueAnimator anim = new ValueAnimator();
        anim.setObjectValues(values);
        anim.setEvaluator(evaluator);
        return anim;
    }

 

以下是IntEvaluator實現的方法,evaluate方法中的具體實現,其值之間的計算遵循方程result = x0+t*(x1-x0)

public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        return (int)(startInt + fraction * (endValue - startInt));
    }

設置動畫int類型初始值。如果在構造ValueAnimator的時候設置了多個初始值,則在調用setIntValues的時候會覆蓋在ofInt傳入的第一個值,以此類推。
public void setIntValues(int... values) {
        if (values == null || values.length == 0) {
            return;
        }
        if (mValues == null || mValues.length == 0) {
            setValues(PropertyValuesHolder.ofInt("", values));
        } else {
            PropertyValuesHolder valuesHolder = mValues[0];
            valuesHolder.setIntValues(values);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    }
設置動畫float類型初始值。如果在ofFloat時候傳入多個參數,則在調用setFloatValues時覆蓋在ofFloat傳入的第一個值,以此類推。
 public void setFloatValues(float... values) {
        if (values == null || values.length == 0) {
            return;
        }
        if (mValues == null || mValues.length == 0) {
            setValues(PropertyValuesHolder.ofFloat("", values));
        } else {
            PropertyValuesHolder valuesHolder = mValues[0];
            valuesHolder.setFloatValues(values);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    }

設置動畫對象初始值。如果初始化傳入多個值,第一個值會被覆蓋。

 

public void setObjectValues(Object... values) {
        if (values == null || values.length == 0) {
            return;
        }
        if (mValues == null || mValues.length == 0) {
            setValues(PropertyValuesHolder.ofObject("", null, values));
        } else {
            PropertyValuesHolder valuesHolder = mValues[0];
            valuesHolder.setObjectValues(values);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    }

設置動畫的屬性初始值。
public void setValues(PropertyValuesHolder... values) {
        int numValues = values.length;
        mValues = values;
        mValuesMap = new HashMap(numValues);
        for (int i = 0; i < numValues; ++i) {
            PropertyValuesHolder valuesHolder = values[i];
            mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    }

返回ValueAnimator動畫中的屬性值,這些值存儲在PropertyValuesHolder對象中。
public PropertyValuesHolder[] getValues() {
        return mValues;
    }
@CallSuper
    void initAnimation() {
        if (!mInitialized) {
            int numValues = mValues.length;
            for (int i = 0; i < numValues; ++i) {
                mValues[i].init();
            }
            mInitialized = true;
        }
    }

設置動畫的總時間。參數duration是非負毫秒數。
 @Override
    public ValueAnimator setDuration(long duration) {
        if (duration < 0) {
            throw new IllegalArgumentException("Animators cannot have negative duration: " +
                    duration);
        }
        mUnscaledDuration = duration;
        updateScaledDuration();
        return this;
    }
private static float sDurationScale = 1.0f;
// How long the animation should last in ms
    private long mDuration = (long)(300 * sDurationScale);
    private long mUnscaledDuration = 300;
private void updateScaledDuration() {//格式轉換
        mDuration = (long)(mUnscaledDuration * sDurationScale);
    }

獲得動畫持續時間。

@Override
    public long getDuration() {
        return mUnscaledDuration;
    }

設置動畫進度為指定的時間點。playTime的值必須在0到總持續時間之間,包括重復動作的。
public void setCurrentPlayTime(long playTime) {
        float fraction = mUnscaledDuration > 0 ? (float) playTime / mUnscaledDuration : 1;
        setCurrentFraction(fraction);
    }

設置指定的動畫進度。fraction值為0時,定位到動畫的開始時刻,值為1時,定位到動畫的結束點,如果fraction值為2,表示動畫重復了1此,且定位到反向動畫的結束點。如果動畫還未開始,setCurrentFraction的設置並不會改變動畫的狀態,如果動畫已經開始了,調用setCurrentFraction,動畫會從設置的點開始繼續運行。fraction的改變不會回調給AnimatorListener監聽。

public static final int INFINITE = -1;表示無限次重復

private int mRepeatCount = 0;動畫重復的次數。

private boolean mPlayingBackwards = false;//表示當前動畫是否是在反向播放,就是倒帶。

public static final int REVERSE = 2;//動畫重復模式,當動畫播放結束且重復次數是一個正值或無限,則對迭代動畫方向取反,就是動畫方向倒帶。

當repeatMode=REVERSE,每個動畫周期反轉一次

public void setCurrentFraction(float fraction) {
        initAnimation();
        if (fraction < 0) {
            fraction = 0;
        }
        int iteration = (int) fraction;
        if (fraction == 1) {
            iteration -= 1;
        } else if (fraction > 1) {
            if (iteration < (mRepeatCount + 1) || mRepeatCount == INFINITE) {
                if (mRepeatMode == REVERSE) {
                    mPlayingBackwards = (iteration % 2) != 0;
                }
                fraction = fraction % 1f;
            } else {
                fraction = 1;
                iteration -= 1;
            }
        } else {
            mPlayingBackwards = mReversing;
        }
        mCurrentIteration = iteration;
        long seekTime = (long) (mDuration * fraction);
        long currentTime = AnimationUtils.currentAnimationTimeMillis();
        mStartTime = currentTime - seekTime;
        mStartTimeCommitted = true; // do not allow start time to be compensated for jank
        if (mPlayingState != RUNNING) {
            mSeekFraction = fraction;
            mPlayingState = SEEKED;
        }
        if (mPlayingBackwards) {
            fraction = 1f - fraction;
        }
        animateValue(fraction);
    }

當前動畫運行的時間點。范圍為0~總時間。如果動畫停止或者動畫的相關參數沒有初始化,則返回0.

 

public long getCurrentPlayTime() {
        if (!mInitialized || mPlayingState == STOPPED) {
            return 0;
        }
        return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
    }

獲取延遲時間,毫秒數

 

 @Override
    public long getStartDelay() {
        return mUnscaledStartDelay;
    }

設置動畫延遲時間。毫秒數

 

@Override
    public void setStartDelay(long startDelay) {
        this.mStartDelay = (long)(startDelay * sDurationScale);
        mUnscaledStartDelay = startDelay;
    }

 

獲取每個幀之間動畫的延遲時間。但是幀之間的實際延遲是不同的,取決於系統的負載和能力。

 

public static long getFrameDelay() {
        return Choreographer.getFrameDelay();
    }

設置幀之間的動畫延遲時間。毫秒數

 

 

public static void setFrameDelay(long frameDelay) {
        Choreographer.setFrameDelay(frameDelay);
    }

ValueAnimator是數值的計算。在初始化對象的時候,傳入了動畫開始值、中間值、結束值等。而ValueAnimator做的就是開始值過渡到結束值之間的一個動畫效果,通過計算將一系列值分布在時間范圍內。而getAnimatedValue就是獲取當前動畫分布的value值。這個值跟開始值、中間值、結束值和動畫時長都有關系。

 

 

public Object getAnimatedValue() {
        if (mValues != null && mValues.length > 0) {
            return mValues[0].getAnimatedValue();
        }
        // Shouldn't get here; should always have values unless ValueAnimator was set up wrong
        return null;
    }

 

 

根據屬性名獲取動畫值。在監聽器AnimatorUpdateListener中回調。
public Object getAnimatedValue(String propertyName) {
        PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
        if (valuesHolder != null) {
            return valuesHolder.getAnimatedValue();
        } else {
            // At least avoid crashing if called with bogus propertyName
            return null;
        }
    }

設置動畫重復次數。

 

public void setRepeatCount(int value) {
        mRepeatCount = value;
    }

獲取動畫重復次數。默認為0或無限次

 

 

public int getRepeatCount() {
        return mRepeatCount;
    }

 

 

設置動畫重復模式。和設置動畫重復次數配合使用

ValueAnimator.RESTART:從頭播放,默認值

ValueAnimator.REVERSE:反向播放。

 public void setRepeatMode(int value) {
        mRepeatMode = value;
    }

獲取動畫重復次數。

 

 

public int getRepeatMode() {
        return mRepeatMode;
    }

 

 

添加監聽器。
public void addUpdateListener(AnimatorUpdateListener listener) {
        if (mUpdateListeners == null) {
            mUpdateListeners = new ArrayList();
        }
        mUpdateListeners.add(listener);
    }

 

移除所有監聽器
 public void removeAllUpdateListeners() {
        if (mUpdateListeners == null) {
            return;
        }
        mUpdateListeners.clear();
        mUpdateListeners = null;
    }

 

移除指定的AnimatorUpdateListener監聽器。
public void removeUpdateListener(AnimatorUpdateListener listener) {
        if (mUpdateListeners == null) {
            return;
        }
        mUpdateListeners.remove(listener);
        if (mUpdateListeners.size() == 0) {
            mUpdateListeners = null;
        }
    }

設置插值器。例如加速器、先加速後減速、自定義插值器等。

 @Override
    public void setInterpolator(TimeInterpolator value) {
        if (value != null) {
            mInterpolator = value;
        } else {
            mInterpolator = new LinearInterpolator();
        }
    }

獲取當前動畫使用的插值器

 

 

@Override
    public TimeInterpolator getInterpolator() {
        return mInterpolator;
    }

 

 

設置估值器。

估值器就是系統告訴動畫如何從初始值到結束值的過渡。例如ofFloat()就是通過FloatEvaluator估值器使得初始值到結束值的平滑過渡。

  public void setEvaluator(TypeEvaluator value) {
        if (value != null && mValues != null && mValues.length > 0) {
            mValues[0].setEvaluator(value);
        }
    }

FloatEvaluator實現TypeEvaluator接口,並重寫了evaluate方法,以下是FloatEvaluator具體實現的方法

 

 public Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }
fraction表示動畫的完成度,是一個比例值,startValue和endValue表示初始值和結束值。FloatEvaluator估值器計算得到動畫值就是結束值減去初始值再乘以fraction系數再加上初始值。估值器計算得到的值就是當前動畫的值。而fraction就是插值器計算出來的。

 

ValueAnimator有三種方法可以對值進行操作,ofFloat、ofInt、ofObject。ofFloat估值器對應FloatEvaluator,ofInt的估值器對應IntEvaluator。這兩個估值器的函數都一樣,只是操作的數值類型不一樣。而ofObject是用於對任意對象的操作,估值器就可以使用我們自定義的。自定義估值器就很好玩了,可以根據自己想要的效果來寫一個函數。

 

顧名思義,就是開始動畫。ValueAnimator繼承了Animator,ValueAnimator具體實現了Animator的抽象方法start。

 

@Override
    public void start() {
        start(false);
    }
以下是start具體實現的代碼,大部分是一些動畫相關值得初始化,值初始化之後真正調用動畫的是animationHandler.start();
private void start(boolean playBackwards) {
        if (Looper.myLooper() == null) {
            throw new AndroidRuntimeException("Animators may only be run on Looper threads");
        }
        mReversing = playBackwards;
        mPlayingBackwards = playBackwards;
        if (playBackwards && mSeekFraction != -1) {
            if (mSeekFraction == 0 && mCurrentIteration == 0) {
                // special case: reversing from seek-to-0 should act as if not seeked at all
                mSeekFraction = 0;
            } else if (mRepeatCount == INFINITE) {
                mSeekFraction = 1 - (mSeekFraction % 1);
            } else {
                mSeekFraction = 1 + mRepeatCount - (mCurrentIteration + mSeekFraction);
            }
            mCurrentIteration = (int) mSeekFraction;
            mSeekFraction = mSeekFraction % 1;
        }
        if (mCurrentIteration > 0 && mRepeatMode == REVERSE &&
                (mCurrentIteration < (mRepeatCount + 1) || mRepeatCount == INFINITE)) {
            // if we were seeked to some other iteration in a reversing animator,
            // figure out the correct direction to start playing based on the iteration
            if (playBackwards) {
                mPlayingBackwards = (mCurrentIteration % 2) == 0;
            } else {
                mPlayingBackwards = (mCurrentIteration % 2) != 0;
            }
        }
        int prevPlayingState = mPlayingState;
        mPlayingState = STOPPED;
        mStarted = true;
        mStartedDelay = false;
        mPaused = false;
        updateScaledDuration(); // in case the scale factor has changed since creation time
        AnimationHandler animationHandler = getOrCreateAnimationHandler();
        animationHandler.mPendingAnimations.add(this);
        if (mStartDelay == 0) {
            // This sets the initial value of the animation, prior to actually starting it running
            if (prevPlayingState != SEEKED) {
                setCurrentPlayTime(0);
            }
            mPlayingState = STOPPED;
            mRunning = true;
            notifyStartListeners();
        }
        animationHandler.start();
    }

 

 

取消動畫。

 @Override
    public void cancel() {
        // Only cancel if the animation is actually running or has been started and is about
        // to run
        AnimationHandler handler = getOrCreateAnimationHandler();
        if (mPlayingState != STOPPED
                || handler.mPendingAnimations.contains(this)
                || handler.mDelayedAnims.contains(this)) {
            // Only notify listeners if the animator has actually started
            if ((mStarted || mRunning) && mListeners != null) {
                if (!mRunning) {
                    // If it's not yet running, then start listeners weren't called. Call them now.
                    notifyStartListeners();
                }
                ArrayList tmpListeners =
                        (ArrayList) mListeners.clone();
                for (AnimatorListener listener : tmpListeners) {
                    listener.onAnimationCancel(this);
                }
            }
            endAnimation(handler);
        }
    }


結束動畫。

 

@Override
    public void end() {
        AnimationHandler handler = getOrCreateAnimationHandler();
        if (!handler.mAnimations.contains(this) && !handler.mPendingAnimations.contains(this)) {
            // Special case if the animation has not yet started; get it ready for ending
            mStartedDelay = false;
            startAnimation(handler);
            mStarted = true;
        } else if (!mInitialized) {
            initAnimation();
        }
        animateValue(mPlayingBackwards ? 0f : 1f);
        endAnimation(handler);
    }

 

 

如果動畫為完成前被pause了,調用resume方法,動畫會從停下的點重新開始。如果動畫已經結束或未開始,調用resume將被忽略

@Override
    public void resume() {
        if (mPaused) {
            mResumed = true;
        }
        super.resume();
    }

暫停動畫。
@Override
    public void pause() {
        boolean previouslyPaused = mPaused;
        super.pause();
        if (!previouslyPaused && mPaused) {
            mPauseTime = -1;
            mResumed = false;
        }
    }

動畫是否在運行中。

 

 @Override
    public boolean isRunning() {
        return (mPlayingState == RUNNING || mRunning);
    }

動畫是否開始了。

 

 

  @Override
    public boolean isStarted() {
        return mStarted;
    }


 

 

 @Override
    public void reverse() {
        mPlayingBackwards = !mPlayingBackwards;
        if (mPlayingState == RUNNING) {
            long currentTime = AnimationUtils.currentAnimationTimeMillis();
            long currentPlayTime = currentTime - mStartTime;
            long timeLeft = mDuration - currentPlayTime;
            mStartTime = currentTime - timeLeft;
            mStartTimeCommitted = true; // do not allow start time to be compensated for jank
            mReversing = !mReversing;
        } else if (mStarted) {
            end();
        } else {
            start(true);
        }
    }


 

 

public float getAnimatedFraction() {
        return mCurrentFraction;
    }


 

 

  @Override
    public ValueAnimator clone() {
        final ValueAnimator anim = (ValueAnimator) super.clone();
        if (mUpdateListeners != null) {
            anim.mUpdateListeners = new ArrayList(mUpdateListeners);
        }
        anim.mSeekFraction = -1;
        anim.mPlayingBackwards = false;
        anim.mReversing = false;
        anim.mCurrentIteration = 0;
        anim.mInitialized = false;
        anim.mPlayingState = STOPPED;
        anim.mStartedDelay = false;
        anim.mStarted = false;
        anim.mRunning = false;
        anim.mPaused = false;
        anim.mResumed = false;
        anim.mStartListenersCalled = false;
        anim.mStartTime = 0;
        anim.mStartTimeCommitted = false;
        anim.mPauseTime = 0;
        anim.mCurrentFraction = 0;
        anim.mDelayStartTime = 0;

        PropertyValuesHolder[] oldValues = mValues;
        if (oldValues != null) {
            int numValues = oldValues.length;
            anim.mValues = new PropertyValuesHolder[numValues];
            anim.mValuesMap = new HashMap(numValues);
            for (int i = 0; i < numValues; ++i) {
                PropertyValuesHolder newValuesHolder = oldValues[i].clone();
                anim.mValues[i] = newValuesHolder;
                anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder);
            }
        }
        return anim;
    }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved