国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android屬性動(dòng)畫之ValueAnimator代碼詳解

2019-10-22 18:15:45
字體:
供稿:網(wǎng)友

屬性動(dòng)畫通過改變一個(gè)對象的屬性值來進(jìn)行動(dòng)畫,屬性動(dòng)畫包含了以下幾個(gè)特性:

1、持續(xù)時(shí)間(Duration)

主要用來定義動(dòng)畫的持續(xù)時(shí)間,默認(rèn)值為300ms。

2、時(shí)間android/250606.html">插值器(Time interpolation)

指定時(shí)間變化的百分比,就是當(dāng)前流逝時(shí)間除以指定的持續(xù)時(shí)間,這個(gè)可以自定義,繼承Interpolator,重寫getInterpolation方法。

3、重復(fù)次數(shù)和行為(Repeat count and behavior)

指定動(dòng)畫的執(zhí)行次數(shù)和動(dòng)畫的重復(fù)模式

4、動(dòng)畫集(Animator sets)

可以把多個(gè)動(dòng)畫放到一個(gè)集合中,是他們同時(shí)執(zhí)行,或者指定它們直接的順序和延遲。

5、Frame refresh delay(幀刷新延遲)

可以指定如何去刷新動(dòng)畫的幀,默認(rèn)是每10ms刷新一次,這個(gè)刷新也取決于系統(tǒng)的繁忙程度。

上面我們知道屬性動(dòng)畫就是改變對象的屬性值來實(shí)現(xiàn)動(dòng)畫,ValueAnimator的特點(diǎn)就是你不需要明確的指定你要改變的對象和屬性,你只需要得到一個(gè)動(dòng)態(tài)的值來自己去設(shè)置相應(yīng)對象的屬性,也就是它就是提供屬性的變化值,你拿到這個(gè)值可以動(dòng)態(tài)的更改對象屬性值。總結(jié)一句就是監(jiān)聽動(dòng)畫過程,自己實(shí)現(xiàn)屬性的改變。

舉個(gè)例子:

// 這里指定了值的變化范圍ValueAnimator animator = ValueAnimator.ofFloat(0, 500);// 這里指定變化持續(xù)時(shí)間animator.setDuration(1000);//開始動(dòng)畫animator.start()//開始動(dòng)畫后,我們可以動(dòng)態(tài)的獲取變化值animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){  @Override  public void onAnimationUpdate(ValueAnimator animation)  {    //根據(jù)變化值來設(shè)置imageView對象的Y軸坐標(biāo),這樣就實(shí)現(xiàn)了imageView的垂直移動(dòng)    imageView.setTranslationY((Float) animation.getAnimatedValue());  }});

上面使用imageView.setTranslationY((Float) animation.getAnimatedValue())來動(dòng)態(tài)的改變圖片的translationY屬性,需要說明的是,如果在低版本中,我們使用的是NineOldAnimations這個(gè)庫,用法跟系統(tǒng)基本一致,在NineOldAnimations里面我們動(dòng)態(tài)改變對象的屬性的時(shí)候,它提供了一個(gè)ViewHelper類,它是設(shè)置各種動(dòng)畫值的幫助類,可以簡單的設(shè)置并應(yīng)用動(dòng)畫值。所以在3.0以下版本中,使用ViewHelper來進(jìn)行屬性值的改變,上面的設(shè)置等同如下:

ViewHelper.setTranslationX(imageView, (Float) animation.getAnimatedValue());

上面的過程如下圖所示:

android,valueanimator,valueanimator詳解,插值器,alpha

上面的過程應(yīng)該比較清晰,在上面我們就設(shè)置了一個(gè)持續(xù)時(shí)間,下面我們可以來看看我們可以為ValueAnimator設(shè)置其他哪些東西。

public ObjectAnimator setDuration(long duration)
設(shè)置持續(xù)時(shí)間

public void setEvaluator(TypeEvaluator value)
設(shè)置估值器

public void setInterpolator(/*Time*/Interpolator value)
設(shè)置插值器

public void setTarget(Object target)
設(shè)置目標(biāo)對象

public void setRepeatCount(int value)
設(shè)置動(dòng)畫重復(fù)次數(shù)

public void setRepeatMode(int value)
設(shè)置重復(fù)模式

public void setValues(PropertyValuesHolder... values)
設(shè)置值

public void setStartDelay(long startDelay)
設(shè)置啟動(dòng)延時(shí)

public static void setFrameDelay(long frameDelay)
設(shè)置幀延遲

public void setIntValues(int... values)
設(shè)置Int值,對應(yīng)ValueAnimator.ofInt函數(shù)

public void setFloatValues(float... values)
設(shè)置Float值。對應(yīng)ValueAnimator.ofFloat函數(shù)

public void setCurrentPlayTime(long playTime)
設(shè)置當(dāng)前執(zhí)行時(shí)間

public void setObjectValues(Object... values)
設(shè)置Object值,對應(yīng)ValueAnimator.ofObject函數(shù)

上面我們知道ValueAnimator是主要提供一個(gè)動(dòng)態(tài)的變化值,這個(gè)值是怎么來變化的,它的變化函數(shù)就是由估值器和插值器來決定的,我們可以自定義估值器和插值器來自定義值的變化,另外這個(gè)變化值的類型,ValueAnimator提供了四種類型,Int,F(xiàn)loat,Objcet,PropertyValuesHolder,它囊括了所有的類型。

1、變化值的類型的確定

我們知道,在我們定義一個(gè)屬性動(dòng)畫對象的時(shí)候,可以不需要通過自己來創(chuàng)建的,主要有四種方式:

public static ValueAnimator ofInt(int... values) public static ValueAnimator ofFloat(int... values)public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values)

從上面我們可以看到,不同的方式其實(shí)對應(yīng)的就是不同類型的變化值。第一種方式的變化值類型為Int,第二種方式的變化值類型為Float,第三種方式的變化值類型為Object,第四種方式的變化值類型為PropertyValuesHolder,它其實(shí)是一個(gè)集合。

2、估值器和插值器

對于給定一個(gè)范圍的值,例如上面例子中ValueAnimator.ofFloat(0, 500),它給定的變化范圍為[0, 500],那么在這個(gè)范圍內(nèi)到底是如何變化的呢?可以是線性變化,可以是加速變化,可以是減速變化,在內(nèi)部已經(jīng)為我們定義好了幾種變化方式,我們可以根據(jù)情況來進(jìn)行使用。

首先我們來說說時(shí)間插值器和類型估值器

TimeInterpolator中文翻譯為時(shí)間插值器,它的作用是根據(jù)時(shí)間流逝的百分比來計(jì)算出當(dāng)前屬性值改變的百分比,系統(tǒng)預(yù)置的有LinearInterpolator(線性插值器:勻速動(dòng)畫)、AccelerateDecelerateInterpolator(加速減速插值器:動(dòng)畫兩頭慢中間快)和DecelerateInterpolator(減速插值器:動(dòng)畫越來越慢)等;

下面看看線性插值器的源碼:

public class LinearInterpolator implements Interpolator {	public LinearInterpolator() {	}	public LinearInterpolator(Context context, AttributeSet attrs) {	}	public float getInterpolation(float input) {		return input;	}}

我們自定義插值器的時(shí)候,只需要重寫getInterpolation方法,其中傳入的input參數(shù)就是時(shí)間流逝的百分比,這個(gè)百分比就是當(dāng)前時(shí)間的流逝除以設(shè)置的持續(xù)時(shí)間Duration來得到的。我們實(shí)現(xiàn)這個(gè)函數(shù)的時(shí)候,可以通過改變這個(gè)值來實(shí)現(xiàn)我們想要的效果。

TypeEvaluator的中文翻譯為類型估值算法,它的作用是根據(jù)當(dāng)前屬性改變的百分比來計(jì)算改變后的屬性值,系統(tǒng)預(yù)置的有IntEvaluator(針對整型屬性)、FloatEvaluator(針對浮點(diǎn)型屬性)和ArgbEvaluator(針對Color屬性)。

我們知道插值器的作用就是返回當(dāng)前屬性改變的百分比,這個(gè)百分比我們可以通過重寫getInterpolation來自定義。其實(shí)真正的變化后的值是從估值器來得到的。

我們來看看IntEvaluator的源碼:

public class IntEvaluator implements TypeEvaluator<Integer> {   public Integer evaluate(float fraction, Integer startValue, Integer endValue) {     int startInt = startValue;     return (int)(startInt + fraction * (endValue - startInt));   } } 

上述算法很簡單,evaluate的三個(gè)參數(shù)分別表示:估值小數(shù)、開始值和結(jié)束值,其中的估值小數(shù)就是上面getInterpolation的返回值,開始值就是變化值的開始,結(jié)束值就是變化值的結(jié)束,對應(yīng)上面例子ValueAnimator.ofFloat(0, 500),開始值為0,結(jié)束值為500,通過這三個(gè)參數(shù),最終計(jì)算出變化后的值,然后將這個(gè)值返回去,我們最終得到的就是這個(gè)值,然后對指定對象的屬性進(jìn)行設(shè)置,這樣來實(shí)現(xiàn)指定屬性值的變化,從而實(shí)現(xiàn)了動(dòng)畫效果。

所以我們?nèi)绻M远x變化值的變化快慢,我們需要自定義一個(gè)插值器和一個(gè)估值器,插值器是為估值器服務(wù)的,估值器是為我們服務(wù)的,因?yàn)樗罱K返回了變化后的值。

最后,我們?nèi)绾蔚玫竭@個(gè)變化后的值呢?從上面的例子中我們可以看到,我們只需要使用ValueAnimator的addUpdateListener函數(shù)來增加一個(gè)更新監(jiān)聽,當(dāng)這個(gè)值變化之后,就會回調(diào)onAnimationUpdate函數(shù),在傳入的參數(shù)ValueAnimator對象中使用getAnimatedValue函數(shù)我們就可以獲取到變化后的那個(gè)值,拿到這個(gè)變化后的值之后我們就可以動(dòng)態(tài)的更新對象的屬性值了。

還有需要注意的是,我們?nèi)绻麤]有顯式指定插值器和估值器,它內(nèi)部有默認(rèn)值。

下面我們來舉個(gè)例子;

/**  * 拋物線  * @param view  */ public void paowuxian(View view) {   ValueAnimator valueAnimator = new ValueAnimator();   valueAnimator.setDuration(3000);   //這個(gè)地方設(shè)置了變化值的類型  valueAnimator.setObjectValues(new PointF(0, 0));   //設(shè)置插值器  valueAnimator.setInterpolator(new LinearInterpolator());   //設(shè)置估值器  valueAnimator.setEvaluator(new TypeEvaluator<PointF>()   {     // fraction = t / duration     @Override     public PointF evaluate(float fraction, PointF startValue,         PointF endValue)     {       Log.e(TAG, fraction * 3 + "");       // x方向200px/s ,則y方向0.5 * 10 * t       PointF point = new PointF();       point.x = 200 * fraction * 3;       point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);       //返回變化值      //這個(gè)返回值會在addUpdateListener的回調(diào)中得到      return point;     }   });   valueAnimator.start();   valueAnimator.addUpdateListener(new AnimatorUpdateListener()   {     @Override     public void onAnimationUpdate(ValueAnimator animation)     {       // 得到估值器里面的那個(gè)返回值      PointF point = (PointF) animation.getAnimatedValue();      //設(shè)置屬性值       mBlueBall.setX(point.x);       mBlueBall.setY(point.y);     }   }); } 

上面基本說清楚了ValueAnimator的特定和用法,下面來說說如何為這個(gè)動(dòng)畫添加事件監(jiān)聽。

ValueAnimator animator = ValueAnimator.ofFloat();animator.setFloatValues(0, 500);animator.setTarget(imageView);animator.setDuration(1000);animator.start();animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){  @Override  public void onAnimationUpdate(ValueAnimator animation)  {    imageView.setTranslationY((Float) animation.getAnimatedValue());  }});animator.addListener(new Animator.AnimatorListener(){  @Override  public void onAnimationStart(Animator animation) {    Log.d(TAG, "onAnimationStart");  }  @Override  public void onAnimationEnd(Animator animation) {    Log.d(TAG, "onAnimationEnd");  }  @Override  public void onAnimationCancel(Animator animation) {    Log.d(TAG, "onAnimationCancel");  }  @Override  public void onAnimationRepeat(Animator animation) {    Log.d(TAG, "onAnimationRepeat");  }});

從上面可以看到直接添加一個(gè)監(jiān)聽就可以了,這樣就可以監(jiān)聽動(dòng)畫的開始、結(jié)束、被取消、重復(fù)等事件,上面你需要重寫上面四個(gè)函數(shù)一個(gè)都不能少,如果你只需要重寫自己需要的函數(shù),那你可以使用AnimatorListenerAdapter,例如只需要重新onAnimationEnd函數(shù),因?yàn)?code>AnimatorListenerAdapter繼承自AnimatorListener

總結(jié)

以上本文關(guān)于Android屬性動(dòng)畫之ValueAnimator代碼詳解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 吕梁市| 沧州市| 浑源县| 囊谦县| 陆良县| 霍邱县| 富蕴县| 博白县| 左贡县| 扎囊县| 固镇县| 勐海县| 土默特左旗| 修武县| 诏安县| 卢湾区| 平阴县| 嘉祥县| 磐安县| 丰县| 嘉黎县| 湾仔区| 农安县| 吉木乃县| 岳阳县| 法库县| 黔西| 梅河口市| 始兴县| 嘉义县| 雅江县| 乌兰县| 玉溪市| 通山县| 隆回县| 邻水| 湖州市| 格尔木市| 辽宁省| 保康县| 南投市|