中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中怎么使用ValueAnimator實現屬性動畫

發布時間:2021-06-29 15:50:25 來源:億速云 閱讀:181 作者:Leah 欄目:移動開發

這期內容當中小編將會給大家帶來有關Android中怎么使用ValueAnimator實現屬性動畫,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1、持續時間(Duration)

主要用來定義動畫的持續時間,默認值為300ms。

2、時間插值器(Time interpolation)

指定時間變化的百分比,就是當前流逝時間除以指定的持續時間,這個可以自定義,繼承Interpolator,重寫getInterpolation方法。

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

指定動畫的執行次數和動畫的重復模式

4、動畫集(Animator sets)

可以把多個動畫放到一個集合中,是他們同時執行,或者指定它們直接的順序和延遲。

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

可以指定如何去刷新動畫的幀,默認是每10ms刷新一次,這個刷新也取決于系統的繁忙程度。

上面我們知道屬性動畫就是改變對象的屬性值來實現動畫,ValueAnimator的特點就是你不需要明確的指定你要改變的對象和屬性,你只需要得到一個動態的值來自己去設置相應對象的屬性,也就是它就是提供屬性的變化值,你拿到這個值可以動態的更改對象屬性值。總結一句就是監聽動畫過程,自己實現屬性的改變。

舉個例子:

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

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

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

上面的過程如下圖所示:

Android中怎么使用ValueAnimator實現屬性動畫

上面的過程應該比較清晰,在上面我們就設置了一個持續時間,下面我們可以來看看我們可以為ValueAnimator設置其他哪些東西。

public ObjectAnimator setDuration(long duration)
設置持續時間

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

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

public void setTarget(Object target)
設置目標對象

public void setRepeatCount(int value)
設置動畫重復次數

public void setRepeatMode(int value)
設置重復模式

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

public void setStartDelay(long startDelay)
設置啟動延時

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

public void setIntValues(int... values)
設置Int值,對應ValueAnimator.ofInt函數

public void setFloatValues(float... values)
設置Float值。對應ValueAnimator.ofFloat函數

public void setCurrentPlayTime(long playTime)
設置當前執行時間

public void setObjectValues(Object... values)
設置Object值,對應ValueAnimator.ofObject函數

上面我們知道ValueAnimator是主要提供一個動態的變化值,這個值是怎么來變化的,它的變化函數就是由估值器和插值器來決定的,我們可以自定義估值器和插值器來自定義值的變化,另外這個變化值的類型,ValueAnimator提供了四種類型,Int,Float,Objcet,PropertyValuesHolder,它囊括了所有的類型。

1、變化值的類型的確定

我們知道,在我們定義一個屬性動畫對象的時候,可以不需要通過自己來創建的,主要有四種方式:

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)

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

2、估值器和插值器

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

首先我們來說說時間插值器和類型估值器

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

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

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

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

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

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

我們來看看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的三個參數分別表示:估值小數、開始值和結束值,其中的估值小數就是上面getInterpolation的返回值,開始值就是變化值的開始,結束值就是變化值的結束,對應上面例子ValueAnimator.ofFloat(0, 500),開始值為0,結束值為500,通過這三個參數,最終計算出變化后的值,然后將這個值返回去,我們最終得到的就是這個值,然后對指定對象的屬性進行設置,這樣來實現指定屬性值的變化,從而實現了動畫效果。

所以我們如果希望自定義變化值的變化快慢,我們需要自定義一個插值器和一個估值器,插值器是為估值器服務的,估值器是為我們服務的,因為它最終返回了變化后的值。

最后,我們如何得到這個變化后的值呢?從上面的例子中我們可以看到,我們只需要使用ValueAnimator的addUpdateListener函數來增加一個更新監聽,當這個值變化之后,就會回調onAnimationUpdate函數,在傳入的參數ValueAnimator對象中使用getAnimatedValue函數我們就可以獲取到變化后的那個值,拿到這個變化后的值之后我們就可以動態的更新對象的屬性值了。

還有需要注意的是,我們如果沒有顯式指定插值器和估值器,它內部有默認值。

下面我們來舉個例子;

/** 
 * 拋物線 
 * @param view 
 */ 
public void paowuxian(View view) 
{ 

  ValueAnimator valueAnimator = new ValueAnimator(); 
  valueAnimator.setDuration(3000); 
  //這個地方設置了變化值的類型
  valueAnimator.setObjectValues(new PointF(0, 0)); 
  //設置插值器
  valueAnimator.setInterpolator(new LinearInterpolator()); 
  //設置估值器
  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); 
      //返回變化值
      //這個返回值會在addUpdateListener的回調中得到
      return point; 
    } 
  }); 

  valueAnimator.start(); 
  valueAnimator.addUpdateListener(new AnimatorUpdateListener() 
  { 
    @Override 
    public void onAnimationUpdate(ValueAnimator animation) 
    { 
      // 得到估值器里面的那個返回值
      PointF point = (PointF) animation.getAnimatedValue();
      //設置屬性值 
      mBlueBall.setX(point.x); 
      mBlueBall.setY(point.y); 

    } 
  }); 
}

上面基本說清楚了ValueAnimator的特定和用法,下面來說說如何為這個動畫添加事件監聽。

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");
  }
});

從上面可以看到直接添加一個監聽就可以了,這樣就可以監聽動畫的開始、結束、被取消、重復等事件,上面你需要重寫上面四個函數一個都不能少,如果你只需要重寫自己需要的函數,那你可以使用AnimatorListenerAdapter,例如只需要重新onAnimationEnd函數,因為AnimatorListenerAdapter繼承自AnimatorListener

上述就是小編為大家分享的Android中怎么使用ValueAnimator實現屬性動畫了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

雷波县| 和平县| 行唐县| 德州市| 米脂县| 旬邑县| 兖州市| 永顺县| 东光县| 龙陵县| 莒南县| 水城县| 徐州市| 松潘县| 赤城县| 富顺县| 韩城市| 互助| 惠东县| 鲁山县| 洪雅县| 彭阳县| 顺平县| 柳林县| 连城县| 鱼台县| 长顺县| 大关县| 钟山县| 清新县| 茶陵县| 松原市| 仙游县| 阿拉善左旗| 阿拉尔市| 团风县| 上犹县| 阿图什市| 孝昌县| 灵石县| 江口县|