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

首頁 > 系統 > Android > 正文

Android屬性動畫(ObjectAnimator)的基本用法

2019-11-06 09:42:11
字體:
來源:轉載
供稿:網友

本篇博客記錄一下Android屬性動畫的基本用法。


1、單屬性變化

Android提供的屬性動畫機制,可以很簡單地調整視圖的屬性值,形成動畫效果。例如:

.............//在3s時間內,將mSunView沿著y軸從start移動到end的位置//其實現的原理是,不斷調用mSunView.setY接口,設置其縱坐標//縱坐標的值,逐漸從start變化到endObjectAnimator heightAnimator = ObjectAnimator .ofFloat(mSunView, "y", start, end) .setDuration(3000);//也可以設置插值器,例如逐漸加速等heightAnimator.setInterpolator(new AccelerateInterpolator());//動畫開始heightAnimator.start();............

ObjectAnimator將根據插值器的規則,將屬性值從start逐漸變化到end。

不過有的屬性值并不適合逐漸變化,例如顏色。 我們知道顏色是用類似于#fcfcb716這種16進制的數字表示的,如果逐漸增加數字,反而會帶來劇烈的色彩變化。 此時ObjectAnimator需要借助TypeEvalutor的子類,精確地計算開始到結束間的遞增指。例如:

.............ObjectAnimator skyAnimator = ObjectAnimator .ofInt(mSkyView, "backgroundColor", start, end) .setDuration(duration);//借助于ArgbEvaluator,精確調整色彩變化的遞進值skyAnimator.setEvaluator(new ArgbEvaluator());skyAnimator.start();.............

2、多屬性同時變化

當需要同時調整多個屬性時,可以使用PRopertyValuesHolder,例如:

................//沿著x軸縮放,縮放比例從start到endPropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", start, end);//沿著y軸縮放,縮放比例從start到endPropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", start, end);//利用ofPropertyValuesHolder接口,可以傳入View對象及多個PropertyValuesHolder//當該動畫開始時,mSunView多個的將同時沿著x、y軸縮放ObjectAnimator.ofPropertyValuesHolder(mSunView, pvhX, pvhY) .setDuration(3000) .start();..........

為了達到同樣的效果,也可以使用AnimatorUpdateListener,例如:

...............ObjectAnimator scaleAnimator = ObjectAnimator //使用一個不存在的屬性,mSunView并不會發生實際的改變 //但生成的值會逐漸從start變化到end .ofFloat(mSunView, "whatever", start, end) .setDuration(3000);//增加AnimatorUpdateListener,生成的值變化時,就會回調onAnimationUpdate接口scaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //得到變化的值 float val = (float)animation.getAnimatedValue(); //調整屬性 mSunView.setScaleX(val); mSunView.setScaleY(val); }});scaleAnimator.start();..............

3、多屬性先后變化

當需要多個屬性先后變化時,就可以AnimatorSet了。 AnimatorSet就是可以放在一起執行的動畫集,其使用方法類似于:

...................@RequiresApi(api = Build.VERSION_CODES.KITKAT)private void startAnimation(boolean isSunSet) { //創建動畫集 mAnimatorSet = new AnimatorSet(); //heightAnimator將和initialSkyAnimator、scaleAnimator、rotateAnimator同時播放 mAnimatorSet.play(getHeightAnimator(isSunSet)) .with(getInitialSkyAnimator(isSunSet)) .with(getScaleAnimator(isSunSet)) .with(getRotateAnimator()) //先于laterSkyAnimator .before(getLaterSkyAnimator(isSunSet)); mAnimatorSet.start();}@RequiresApi(api = Build.VERSION_CODES.KITKAT)private ObjectAnimator getHeightAnimator(boolean isSunset) { float sunYStart = mSunView.getTop(); float sunYEnd = mSkyView.getHeight() + mSunView.getBottom() - mSunView.getTop(); final float start = isSunset ? sunYStart : sunYEnd; final float end = isSunset ? sunYEnd : sunYStart; ObjectAnimator heightAnimator = ObjectAnimator .ofFloat(mSunView, "y", start, end) .setDuration(3000); heightAnimator.setInterpolator(new AccelerateInterpolator()); return heightAnimator;}private ObjectAnimator getInitialSkyAnimator(boolean isSunset) { int start = isSunset ? mBlueSkyColor : mNightSkyColor; int end = mSunsetSkyColor; return createSkyAnimator(start, end, 3000);}private ObjectAnimator getLaterSkyAnimator(boolean isSunset) { int start = mSunsetSkyColor; int end = isSunset ? mNightSkyColor : mBlueSkyColor; return createSkyAnimator(start, end, 1500);}private ObjectAnimator createSkyAnimator(int start, int end, int duration) { ObjectAnimator skyAnimator = ObjectAnimator .ofInt(mSkyView, "backgroundColor", start, end) .setDuration(duration); skyAnimator.setEvaluator(new ArgbEvaluator()); return skyAnimator;}private ObjectAnimator getScaleAnimator(boolean isSunSet) { float start = (float) (isSunSet ? 1 : 1.5); float end = (float) (isSunSet ? 1.5 : 1); PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", start, end); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", start, end); return ObjectAnimator.ofPropertyValuesHolder(mSunView, pvhX, pvhY) .setDuration(3000); return scaleAnimator;}private ObjectAnimator getRotateAnimator() { ObjectAnimator objectAnimator = ObjectAnimator .ofFloat(mSunView, "rotation", 0, 360) .setDuration(1000); objectAnimator.setRepeatCount(4); return objectAnimator;}.................

4、狀態判斷和回調接口

AnimatorSet繼承Animator,具有同樣的接口判斷動畫執行的狀態,例如:

@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_sunset, container, false); .............. v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (Build.VERSION.SDK_INT >= 19) { //isStarted判斷動畫是否已經開始(動畫暫停時,isStarted返回的也是true) if (mAnimatorSet == null || !mAnimatorSet.isStarted()) { startAnimation(); } else { //isPaused判斷動畫是否暫停 if (mAnimatorSet.isPaused()) { //resume繼續播放動畫 mAnimatorSet.resume(); } else { //pause暫停播放動畫 mAnimatorSet.pause(); } } } } }); return v;}

與上述狀態變化接口對應,Animator及其子類均可以利用AnimatorListener監聽動畫的狀態:

..............mAnimatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { .............. } @Override public void onAnimationEnd(Animator animation) { .............. } @Override public void onAnimationCancel(Animator animation) { .............. } @Override public void onAnimationRepeat(Animator animation) { .............. }});

Animator運行到不同的狀態時,將回調AnimatorListener相應的接口。 例如,利用AnimatorListener也可以做到一個動畫結束時,啟動下一個動畫。 只要在AnimatorListener.onAnimationEnd中啟動下一個動畫即可。


5、逆向播放動畫示例

假設現在有個需求,需要點擊屏幕后,逆向播放已經放過的動畫。 即一個View從高度A下降到B時,點擊屏幕,View從B上升到A。

顯然動畫包含的屬性越是復雜,完全逆向就越困難。 不過實現的思路大概是,保存初始和暫停的狀態,然后構造逆向的ObjectAnimator,示例如下:

................private long mCurrentPlayTime = 0;private float mCurrentHeight = 0;@RequiresApi(api = Build.VERSION_CODES.KITKAT)private ObjectAnimator getHeightAnimator(boolean isSunset) { float sunYStart = mSunView.getTop(); float sunYEnd = mSkyView.getHeight() + mSunView.getBottom() - mSunView.getTop(); final float start = isSunset ? sunYStart : sunYEnd; final float end = isSunset ? sunYEnd : sunYStart; ObjectAnimator heightAnimator = ObjectAnimator .ofFloat(mSunView, "y", start, end) .setDuration(3000); heightAnimator.setInterpolator(new AccelerateInterpolator()); //利用AnimatorUpdateListener記錄動畫執行時的中間狀態 heightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurrentPlayTime = animation.getCurrentPlayTime(); mCurrentHeight = (float)animation.getAnimatedValue(); } }); heightAnimator.addPauseListener(new Animator.AnimatorPauseListener() { @Override public void onAnimationPause(Animator animation) { heightAnimator = ObjectAnimator //從當前位置變化到初始位置 .ofFloat(mSunView, "y", mCurrentHeight, start) //執行時間為已經播放的時間 .setDuration(mCurrentPlayTime); //逐漸減速 heightAnimator.setInterpolator(new DecelerateInterpolator()); //取消之前的動畫 //這里只是示范一下,如果整個AnimatorSet逆向 //則因該在AnimatorSet的AnimatorPauseListener中重構整個AnimatorSet mAnimatorSet.cancel(); //開始新的動畫 heightAnimator.start(); } @Override public void onAnimationResume(Animator animation) { } }); return heightAnimator;}.........

以上就是屬性動畫的一些基本用法,以后遇到新的知識再作進一步補充。

P.S. : 最后補充一下,視圖中各個屬性的基本含義:


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 吉安市| 房山区| 新巴尔虎右旗| 犍为县| 铁力市| 常山县| 闸北区| 惠水县| 大埔区| 邵武市| 遂平县| 司法| 元朗区| 蒲江县| 枣阳市| 岳阳市| 仁寿县| 丰城市| 丹阳市| 松江区| 汝州市| 长子县| 抚宁县| 城步| 徐汇区| 吴旗县| 哈尔滨市| 金川县| 长阳| 临澧县| 宁安市| 壶关县| 黄龙县| 柘城县| 齐河县| 乡宁县| 邳州市| 平顺县| 四平市| 蓬莱市| 赤壁市|