Android動畫系列之屬性動畫的基本使用教程
前言
屬性動畫相較幀動畫和補間動畫更強大,幀動畫和補間動畫只能應用于 View 及其子類,而屬性動畫可以修改任何對象的屬性值,屬性值可在指定的一段時間內(nèi)自動改變,根據(jù)對象屬性值的變化進而實現(xiàn)更復雜的動畫。
- 屬性動畫的常用設置
- ValueAnimator
- ObjectAnimator
- 關鍵幀
- 插值器和估值器
屬性動畫的常用設置
下面是屬性動畫的常用設置,具體如下:
//設置屬性動畫持續(xù)時間 animator.setDuration(2000); //設置屬性插值器 animator.setInterpolator(new AccelerateInterpolator()); //設置屬性動畫重復播放模式 animator.setRepeatMode(ValueAnimator.REVERSE); //設置屬性動畫重復播放次數(shù) animator.setRepeatCount(0); //設置屬性動畫延時播放的時間 animator.setStartDelay(0); //設置屬性動畫估值器,用于控制最終屬性值(API22) animator.setCurrentFraction(0.5f); //設置當前播放時間,其值在Duration范圍之內(nèi) animator.setCurrentPlayTime(1000); //設置屬性動畫估值器,用于控制最終屬性值 animator.setEvaluator(new IntEvaluator()); //設置屬性動畫監(jiān)聽 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Log.i(TAG, animation.getAnimatedValue() + ""); // } }); //...
ValueAnimator
ValueAnimator 提供了一個簡單的計時引擎,用于執(zhí)行動畫時根據(jù)設置的時長以及其他屬相完成動畫值的計算,然后就可以將動畫值設置到合適的目標對象上,使用的插值器默認時 AccelerateDecelerateInterpolator,表示動畫開始和結束時較慢,中間加速完成動畫,下面是源碼中默認的插值器,具體如下:
// The time interpolator to be used if none is set on the animation private static final TimeInterpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator();
在 ValueAnimator 中已經(jīng)內(nèi)部處理了一些估值器 IntEvaluator 和 FloatEvaluator,也就是說如果使用的時 ofInt 和 ofFloat 方法作為動畫的屬性值,那么 ValueAnimator 會自動處理 int 和 float 值的變化,在源碼中找了一下,這部分內(nèi)容在 PropertyValuesHolder 這個類中,具體如下:
void init() { if (mEvaluator == null) { // We already handle int and float automatically, but not their Object // equivalents mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : (mValueType == Float.class) ? sFloatEvaluator : null; } if (mEvaluator != null) { // KeyframeSet knows how to evaluate the common types - only give it a custom // evaluator if one has been set on this class mKeyframes.setEvaluator(mEvaluator); } }
ValueAnimator 可以使用代碼創(chuàng)建,也可以使用 xml 創(chuàng)建,下面以平移動畫為例說明 ValueAnimator 的使用方式,其他如縮放、旋轉等使用方式類似。
使用代碼創(chuàng)建
private void translation(){ ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100); valueAnimator.setDuration(2000); valueAnimator.setInterpolator(new AccelerateInterpolator()); valueAnimator.setRepeatMode(ValueAnimator.REVERSE); valueAnimator.setRepeatCount(0); valueAnimator.setStartDelay(0); // valueAnimator.setCurrentFraction(0.5f); // valueAnimator.setCurrentPlayTime(1000); valueAnimator.setEvaluator(new IntEvaluator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Log.i(TAG, animation.getAnimatedValue() + ""); int x = (int) animation.getAnimatedValue(); ivImage.setTranslationX(x); ivImage.setTranslationY(x); } }); valueAnimator.start(); }
使用xml創(chuàng)建
在 res/animator 文件夾下創(chuàng)建 test_animator.xml 文件,文件內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?> <animator xmlns:android="http://schemas.android.com/apk/res/android" android:valueFrom="0" android:valueTo="100" android:valueType="intType" android:duration="2000" android:startOffset ="0" android:repeatMode = "reverse" android:repeatCount = "0" android:interpolator = "@android:anim/accelerate_interpolator"> </animator>
然后在 Activity 中獲取 ValueAnimator,設置目標對象,啟動動畫即可,具體如下:
private void translation(){ ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.test_animator); animator.setTarget(ivImage); animator.start(); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Log.i(TAG, animation.getAnimatedValue() + ""); int x = (int) animation.getAnimatedValue(); ivImage.setTranslationX(x); ivImage.setTranslationY(x); } }); }
測試效果
這里使用 ValueAnimator 來實現(xiàn)平移動畫,測試效果如下:
ObjectAnimator
ObjectAnimator 是 ValueAnimator 的子類,可在目標對象上支持動畫屬性的設置,在其構造方法中通過參數(shù)指定目標對象以及所對應動畫屬性的名稱,然后會相應的執(zhí)行對應的動畫屬性的 setter 方法來最終完成動畫的執(zhí)行,也就是說屬性動畫 ObjectAnimator 最終調用目標對象的 setter 方法完成目標對象屬性值的變化,然后相應的改變目標對象的屬性,從而實現(xiàn)目標對象的動畫效果,下面以透明度變化來介紹 ObjectAnimator 的基本使用,代碼參考如下:
private void alpha(){ ObjectAnimator animator = ObjectAnimator.ofFloat(ivImage,"alpha",1f,0,1f); animator.setDuration(3000); //其他屬性動畫設置 //... animator.start(); }
下面是測試效果,如下圖所示:
至于平移、旋轉、縮放動畫實現(xiàn)方式基本如上,這里不再贅述,其對應的 setter 方法對應關系如下:
屬性 | 作用 | 對應方法 |
---|---|---|
Alpha | 控制View的透明度 | setAlpha |
TranslationX | 控制X方向的位移 | setTranslationX |
TranslationY | 控制Y方向的位移 | setTranslationY |
ScaleX | 控制X方向的縮放倍數(shù) | setScaleX |
ScaleY | 控制Y方向的縮放倍數(shù) | setScaleY |
Rotation | 控制以屏幕方向為軸的旋轉度數(shù) | setRotation |
RotationX | 控制以X軸為軸的旋轉度數(shù) | setRotationX |
RotationY | 控制以Y軸為軸的旋轉度數(shù) | setRotationY |
ObjectAnimator 提供了很多的 ofXxx() 方法來方面設置屬性動畫,如下圖所示:
可根據(jù)不同的動畫需求使用 ObjectValueAnimator 不同 ofXxx() 方法來實現(xiàn)相應的動畫。
關鍵幀
這里簡單說一下關鍵幀的使用,顧名思義關鍵幀就是在某個固定時刻上定義具體的屬性值,為定義的將按照估值器返回的值返回屬性值,屬性動畫中的關鍵幀使用方式如下:
/** * 關鍵幀的使用 */ private void keyFrame(){ Keyframe keyframe1 = Keyframe.ofFloat(0,0); Keyframe keyframe2 = Keyframe.ofFloat(0.25f,300); //每個KeyFrame可設置自己的插值器 keyframe2.setInterpolator(new AccelerateInterpolator()); Keyframe keyframe3 = Keyframe.ofFloat(0.75f,100); Keyframe keyframe4 = Keyframe.ofFloat(1,400); PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationX",keyframe1,keyframe2,keyframe3,keyframe4); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(ivImage,holder); animator.setDuration(3000); animator.start(); }
看一下添加關鍵幀之后對普通平移動畫的改變,實現(xiàn)測試效果如下:
插值器和估值器
插值器(TimeInterpolator) 表示的是整個動畫期間動畫的變化規(guī)律,如加速、減速等。
Android 內(nèi)置許多插值器,這些插值器基本涵蓋了實際開發(fā)中的大部分情況,具體如下:
如果內(nèi)置的插值器不滿足需求,也可以自定義插值器。
估值器(TypeEvaluator)表示的是在整個動畫期間各時刻屬性值的具體變化。
這里自定義一個估值器來實現(xiàn)一個 View 沿正弦曲線運動,自定義估值器如下:
/** * 自定義估值器 * Point封裝了坐標x和y */ public class SineTypeValue implements TypeEvaluator<Point> { @Override public Point evaluate(float fraction, Point startValue, Point endValue) { //y = sinA float distance = fraction * (endValue.getX() - startValue.getX()); float x = startValue.getX() + distance; float y = startValue.getY() + (float) Math.sin(distance / 100 * Math.PI) * 100; Point point = new Point(); point.setX(x); point.setY(y); return point; } }
然后給動畫設置該估值器,監(jiān)聽動畫屬性設置 View 的位置即可實現(xiàn)一個 View 沿正弦曲線運動,使用方式如下:
/** * 自定義估值器的使用 * 正弦運動的估值器 */ private void sina(){ Point startPoint = new Point(ivImage.getX(),ivImage.getY()); Point endPoint = new Point(ivImage.getX()+500,ivImage.getY()); ValueAnimator valueAnimator = ValueAnimator.ofObject(new SineTypeValue(), startPoint, endPoint); valueAnimator.setDuration(5000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Log.i(TAG, animation.getAnimatedValue() + ""); Point point = (Point) animation.getAnimatedValue(); ivImage.setX(point.getX()); ivImage.setY(point.getY()); } }); valueAnimator.start(); }
測試效果如下:
自定義估值器
到此這篇關于Android動畫系列之屬性動畫基本使用的文章就介紹到這了,更多相關Android屬性動畫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android開發(fā)之OkHttpUtils的具體使用方法
這篇文章主要介紹了Android開發(fā)之OkHttpUtils的具體使用方法,非常具有實用價值,需要的朋友可以參考下2017-08-08Android自定義Dialog實現(xiàn)加載對話框效果
這篇文章將介紹如何定制當今主流的對話框,通過自定義dialog實現(xiàn)加載對話框效果,具體實現(xiàn)代碼大家通過本文學習吧2018-05-05Android編程實現(xiàn)自定義輸入法功能示例【輸入密碼時防止第三方竊取】
這篇文章主要介紹了Android編程實現(xiàn)自定義輸入法功能,可實習輸入密碼時防止第三方竊取的效果,結合實例形式詳細分析了Android布局、控件及輸入法相關操作技巧,需要的朋友可以參考下2017-01-01