动画代码Android动画学习笔记动画代码
間時緊張,先記一筆,后續(xù)優(yōu)化與完善。
????3.0之前,android支撐兩種動畫模式,tween animation,frame animation,在android3.0中又引入了一個新的動畫統(tǒng)系:property animation,這三種動畫模式在SDK中被稱為property animation,view animation,drawable animation。?
????
1. View Animation(Tween Animation)
????View Animation(Tween Animation):補間動畫,給出兩個鍵關(guān)幀,通過一些算法將給定性屬值在給定的間時內(nèi)涵兩個鍵關(guān)幀間漸變。
????View animation只能應用于View象對,而且只支撐一部分性屬,如支撐縮放旋轉(zhuǎn)而不支撐背景顏色的轉(zhuǎn)變。
????而且對于View animation,它只是轉(zhuǎn)變了View象對制繪的置位,而沒有轉(zhuǎn)變View象對本身,比如,你有一個Button,標坐(100,100),Width:200,Height:50,而你有一個動畫使其變成Width:100,Height:100,你會發(fā)明動畫中程過觸發(fā)鈕按點擊的區(qū)域還是(100,100)-(300,150)。
????View Animation就是一系列View外形的換變,如巨細的縮放,明透度的轉(zhuǎn)變,置位的轉(zhuǎn)變,動畫的定義既可以用代碼定義也可以用XML定義,當然,議建用XML定義。
????可以給一個View同時設(shè)置多個動畫,比如從明透至不明透的淡入效果,與從小到大的放大效果,這些動畫可以同時停止,也可以在一個實現(xiàn)后之開始另一個。
????用XML定義的動畫放在/res/anim/文件夾內(nèi),XML文件的根素元可為以<alpha>,<scale>,<translate>,<rotate>,interpolator素元或<set>(示表以上幾個動畫的集合,set可以嵌套)。認默情況下,全體動畫是同時停止的,可以通過startOffset性屬設(shè)置各個動畫的開始移偏(開始間時)來到達動畫次序放播的效果。
????可以通過設(shè)置interpolator性屬轉(zhuǎn)變動畫漸變的方法,如AccelerateInterpolator,開始時慢,然后漸逐快加。認默為AccelerateDecelerateInterpolator。
????定義好動畫的XML文件后,可以通過似類面下的代碼對指定View應用動畫。
ImageView spaceshipImage = (ImageView)findViewById(R.id.spaceshipImage);Animation hyperspaceJumpAnimation=AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
spaceshipImage.startAnimation(hyperspaceJumpAnimation);
2. Drawable Animation(Frame Animation)
????Drawable Animation(Frame Animation):幀動畫,就像GIF圖片,通過一系列Drawable順次示顯來模擬動畫的效果。在XML中的定義方法如下:
????
?| 1 2 3 4 5 6 | < animation-list? xmlns:android = "http://schemas.android.com/apk/res/android" ???? android:oneshot = "true" > ???? < item? android:drawable = "@drawable/rocket_thrust1"? android:duration = "200"? /> ???? < item? android:drawable = "@drawable/rocket_thrust2"? android:duration = "200"? /> ???? < item? android:drawable = "@drawable/rocket_thrust3"? android:duration = "200"? /> </ animation-list > |
????必須以<animation-list>為根素元,以<item>示表要輪換示顯的圖片,duration性屬示表各項示顯的間時。XML文件要放在/res/drawable/目錄下。示例:
protected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView) findViewById(R.id.imageView1);
imageView.setBackgroundResource(R.drawable.drawable_anim);
anim = (AnimationDrawable) imageView.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
anim.stop();
anim.start();
return true;
}
return super.onTouchEvent(event);
}
我在試驗中到遇兩點問題:
????
????
3. Property Animation
????性屬動畫,這個是在Android 3.0中才引進的,之前學WPF時面里的動畫機制似乎就是這個,它變動的是象對的現(xiàn)實性屬,在View Animation(Tween Animation)中,其轉(zhuǎn)變的是View的制繪效果,真正的View的性屬持保變不,比如無論你在對話中如何縮放Button的巨細,Button的有效點擊區(qū)域還是沒有應用動畫時的區(qū)域,其置位與巨細都變不。而在Property Animation中,轉(zhuǎn)變的是象對的現(xiàn)實性屬,如Button的縮放,Button的置位與巨細性屬值都轉(zhuǎn)變了。而且Property Animation不止可以應用于View,還可以應用于任何象對。Property Animation只是示表一個值在一段間時內(nèi)的轉(zhuǎn)變,當值轉(zhuǎn)變時要做什么事情完整是你自己定決的。
????在Property Animation中,可以對動畫應用以下性屬:
????
- Duration:動畫的持續(xù)間時
- TimeInterpolation:性屬值的算計方法,如先快后慢
- TypeEvaluator:根據(jù)性屬的開始、結(jié)束值與TimeInterpolation算計出的因子算計出前當間時的性屬值
- Repeat Country and behavoir:復重次數(shù)與方法,如放播3次、5次、無限環(huán)循,可以此動畫始終復重,或放播完時再反向放播
- Animation sets:動畫集合,即可以同時對一個象對應用幾個動畫,這些動畫可以同時放播也可以對不同動畫設(shè)置不同開始移偏
- Frame refreash delay:多少間時新刷一次,即每隔多少間時算計一次性屬值,認默為10ms,終最新刷間時還受統(tǒng)系進程調(diào)度與硬件的影響
????
3.1 Property Animation的任務(wù)方法
????對于下圖的動畫,這個象對的X標坐在40ms內(nèi)從0動移到40 pixel.按認默的10ms新刷一次,這個象對會動移4次,每次動移40/4=10pixel。
????
????也可以轉(zhuǎn)變性屬值的轉(zhuǎn)變方法,即設(shè)置不同的interpolation,在下圖中動運度速先漸逐增大再漸逐減小
????
????下圖示顯了與上述動畫關(guān)相的鍵關(guān)象對
????
????ValueAnimator即示表一個動畫,包括動畫的開始值,結(jié)束值,持續(xù)間時等性屬。
????ValueAnimator裝封了一個TimeInterpolator,TimeInterpolator定義了性屬值在開始值與結(jié)束值之間的插值方法。
????ValueAnimator還裝封了一個TypeAnimator,根據(jù)開始、結(jié)束值與TimeIniterpolator算計失掉的值算計出性屬值。
????ValueAnimator根據(jù)動畫已停止的間時跟動畫總間時(duration)的比算計出一個間時因子(0~1),然后根據(jù)TimeInterpolator算計出另一個因子,最后TypeAnimator通過這個因子算計出性屬值,如上例中10ms時:
????首先算計出間時因子,即經(jīng)過的間時百分比:t=10ms/40ms=0.25
????經(jīng)插值算計(inteplator)后的插值因子:大約為0.15,上述例子中用了AccelerateDecelerateInterpolator,算計公式為(input即為間時因子):
(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;最后根據(jù)TypeEvaluator算計出在10ms時的性屬值:0.15*(40-0)=6pixel。上例中TypeEvaluator為FloatEvaluator,算計方法為 :
public Float evaluate(float fraction, Number startValue, Number endValue) {float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
參數(shù)分別為上一步的插值因子,開始值與結(jié)束值。
????
3.2 ValueAnimator
????ValueAnimator包括Property Animation動畫的全體核心功能,如動畫間時,開始、結(jié)束性屬值,響應間時性屬值算計方法等。應用Property Animation有兩個步聚:
????
????ValuAnimiator只實現(xiàn)了第一步任務(wù),如果要實現(xiàn)第二步,要需實現(xiàn)ValueAnimator.onUpdateListener接口,如:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);animation.setDuration(1000);
animation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("update", ((Float) animation.getAnimatedValue()).toString());
}
});
animation.setInterpolator(new CycleInterpolator(3));
animation.start();
此示例中只是向Logcat輸出了一些息信,可為以改想做的任務(wù)。
????Animator.AnimatorListener
onAnimationStart()onAnimationEnd()
onAnimationRepeat()
onAnimationCancel
ValueAnimator.AnimatorUpdateListener
onAnimationUpdate() //通過監(jiān)聽這個件事在性屬的值更新時執(zhí)行響應的操縱,對于ValueAnimator一般要監(jiān)聽此件事執(zhí)行響應的動作,不然Animation沒義意(可用于計時),在ObjectAnimator(承繼自ValueAnimator)中會主動更新性屬,如無要必不必監(jiān)聽。在函數(shù)中會傳遞一個ValueAnimator參數(shù),通過此參數(shù)的getAnimatedValue()獲得前當動畫性屬值。可以承繼AnimatorListenerAdapter而不是實現(xiàn)AnimatorListener接口來簡化操縱,這個類對AnimatorListener中的函數(shù)都定義了一個空函數(shù)體,這樣我們就只用定義想監(jiān)聽的件事而不必實現(xiàn)每一個函數(shù)卻只定義一空函數(shù)體。
ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);oa.setDuration(3000);
oa.addListener(new AnimatorListenerAdapter(){
public void on AnimationEnd(Animator animation){
Log.i("Animation","end");
}
});
oa.start();
3.3 ObjectAnimator
????承繼自ValueAnimator,要指定一個象對及該象對的一個性屬,當性屬值算計實現(xiàn)時主動設(shè)置為該象對的響應性屬,即實現(xiàn)了Property Animation的全體兩步操縱。現(xiàn)實應用中一般都會用ObjectAnimator來轉(zhuǎn)變某一象對的某一性屬,但用ObjectAnimator有定一的制約,要想應用ObjectAnimator,該應足滿以下條件:
????
- 象對該應有一個setter函數(shù):set<PropertyName>(駝峰名命法)
- 如上面的例子中,像ofFloat之類的工廠方法,第一個參數(shù)為象對名,第二個為性屬名,面后的參數(shù)為可變參數(shù),如果values…參數(shù)只設(shè)置了一個值的話,那么會假定為目標值,性屬值的化變圍范為前當值到目標值,為了得獲前當值,該象對要有響應性屬的getter方法:get<PropertyName>
- 如果有g(shù)etter方法,其應返回值類型應與響應的setter方法的參數(shù)類型分歧。
????如果上述條件不足滿,則不能用ObjectAnimator,應用ValueAnimator替代。
tv=(TextView)findViewById(R.id.textview1);btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f);
oa.setDuration(3000);
oa.start();
}
});
把一個TextView的明透度在3秒內(nèi)從0變至1。
???? 根據(jù)應用動畫的象對或性屬的不同,可能要需在onAnimationUpdate函數(shù)中調(diào)用invalidate()函數(shù)新刷視圖。
????
3.4 通過AnimationSet應用多個動畫
????AnimationSet供提了一個把多個動畫組合成一個組合的機制,并可設(shè)置組中動畫的時序系關(guān),如同時放播,次序放播等。
????以下例子同時應用5個動畫:
????
????
?| 1 2 3 4 5 6 | AnimatorSet bouncer = new? AnimatorSet(); bouncer.play(anim1).before(anim2); bouncer.play(anim2).with(anim3); bouncer.play(anim2).with(anim4) bouncer.play(anim5).after(amin2); animatorSet.start(); |
????
3.5 TypeEvalutors
????根據(jù)性屬的開始、結(jié)束值與TimeInterpolation算計出的因子算計出前當間時的性屬值,android供提了以下幾個evalutor:
????
- IntEvaluator:性屬的值類型為int;
- FloatEvaluator:性屬的值類型為float;
- ArgbEvaluator:性屬的值類型為十六進制顏色值;
- TypeEvaluator:一個接口,可以通過實現(xiàn)該接口自定義Evaluator。
????自定義TypeEvalutor很簡單,只要需實現(xiàn)一個方法,如FloatEvalutor的定義:
????
?| 1 2 3 4 5 6 | public? class? FloatEvaluator implements? TypeEvaluator { ???? public? Object evaluate( float? fraction, Object startValue, Object endValue) { ???????? float? startFloat = ((Number) startValue).floatValue(); ???????? return? startFloat + fraction * (((Number) endValue).floatValue() - startFloat); ???? } } |
????根據(jù)動畫執(zhí)行的間時跟應用的Interplator,會算計出一個0~1之間的因子,即evalute函數(shù)中的fraction參數(shù),通過上述FloatEvaluator該應很好看出其意思。
????
3.6 TimeInterplator
????time interplator定義了性屬值化變的方法,如性線平均轉(zhuǎn)變,開始慢然后漸逐快等。在Property Animation中是TimeInterplator,在View Animation中是Interplator,這兩個是一樣的,在3.0之前只有Interplator,3.0后之實現(xiàn)代碼轉(zhuǎn)移至了TimeInterplator。Interplator承繼自TimeInterplator,部內(nèi)沒有任何其他代碼。
?
????
- AccelerateInterpolator ? ? 減速,開始時慢旁邊減速
- DecelerateInterpolator ? 減速,開始時快然后減速
- AccelerateDecelerateInterolator ? 先減速后減速,開始結(jié)束時慢,旁邊減速
- AnticipateInterpolator ?反向 ,先向相反向方轉(zhuǎn)變一段再減速放播
- AnticipateOvershootInterpolator 反向加超出,先向相反向方轉(zhuǎn)變,再減速放播,會超出目標值然后遲緩動移至目標值
- BounceInterpolator ?躍跳,快到目標值時值會躍跳,如目標值100,面后的值可能順次為85,77,70,80,90,100
- CycleIinterpolator ?環(huán)循,動畫環(huán)循定一次數(shù),值的轉(zhuǎn)變成一正弦函數(shù):Math.sin(2 * mCycles * Math.PI * input)
- LinearInterpolator ?性線,性線平均轉(zhuǎn)變
- OvershottInterpolator ?超出,最后超出目標值然后遲緩轉(zhuǎn)變到目標值
- TimeInterpolator 一個接口,答應你自定義interpolator,以上幾個都是實現(xiàn)了這個接口
????
3.7 當Layout轉(zhuǎn)變時應用動畫
????ViewGroup中的子素元可以通過setVisibility使其Visible、Invisible或Gone,當有子素元可見性轉(zhuǎn)變時,可以向其應用動畫,通過LayoutTransition類應用此類動畫:
transition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);通過setAnimator應用動畫,第一個參數(shù)示表應用的情境,可以以下4種類型:
????
- APPEARING 當一個素元變成Visible時對其應用的動畫
- CHANGE_APPEARING 當一個素元變成Visible時,因統(tǒng)系要新重局布有一些素元要需動移,這些要動移的素元應用的動畫
- DISAPPEARING 當一個素元變成InVisible時對其應用的動畫
- CHANGE_DISAPPEARING 當一個素元變成Gone時,因統(tǒng)系要新重局布有一些素元要需動移,這些要動移的素元應用的動畫?disappearing from the container.
????第二個參數(shù)為一Animator。
mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);此函數(shù)設(shè)置動畫持續(xù)間時,參數(shù)分別為類型與間時。
????
3.8 Keyframes
????keyFrame是一個 間時/值 對,通過它可以定義一個在特定間時的特定狀態(tài),而且在兩個keyFrame之間可以定義不同的Interpolator,就當相多個動畫的拼接,第一個動畫的結(jié)點束是第二個動畫的開始點。KeyFrame是抽象類,要通過ofInt(),ofFloat(),ofObject()得獲當適的KeyFrame,然后通過PropertyValuesHolder.ofKeyframe得獲PropertyValuesHolder象對,如以下例子:
Keyframe kf0 = Keyframe.ofInt(0, 400);Keyframe kf1 = Keyframe.ofInt(0.25f, 200);
Keyframe kf2 = Keyframe.ofInt(0.5f, 400);
Keyframe kf4 = Keyframe.ofInt(0.75f, 100);
Keyframe kf3 = Keyframe.ofInt(1f, 500);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf4, kf3);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(btn2, pvhRotation);
rotationAnim.setDuration(2000);
上述代碼的意思為:設(shè)置btn象對的width性屬值使其:
????
- 開始時 Width=400
- 動畫開始1/4時 Width=200
- 動畫開始1/2時 Width=400
- 動畫開始3/4時 Width=100
- 動畫結(jié)束時 Width=500
????
第一個參數(shù)為間時百分比,第二個參數(shù)是在第一個參數(shù)的間時時的性屬值。????
定義了一些Keyframe后,通過PropertyValuesHolder類的方法ofKeyframe裝封,然后通過ObjectAnimator.ofPropertyValuesHolder得獲Animator。????
用面下的代碼可以實現(xiàn)樣同的效果: ObjectAnimator oa=ObjectAnimator.ofInt(btn2, "width", 400,200,400,100,500);oa.setDuration(2000);
oa.start();
3.9 Animating Views
????在View Animation中,對View應用Animation并沒有轉(zhuǎn)變View的性屬,動畫的實現(xiàn)是通過其Parent View實現(xiàn)的,在View被drawn時Parents View轉(zhuǎn)變它的制繪參數(shù),draw后再轉(zhuǎn)變參數(shù)invalidate,這樣雖然View的巨細或旋轉(zhuǎn)角度等轉(zhuǎn)變了,但View的現(xiàn)實性屬沒變,所以有效區(qū)域還是應用動畫之前的區(qū)域,比如你把一鈕按放大兩倍,但還是放大這前的區(qū)域可以觸發(fā)點擊件事。為了轉(zhuǎn)變這一點,在Android 3.0中給View增加了一些參數(shù)并對這些參數(shù)增加了響應的getter/setter函數(shù)(ObjectAnimator要用這些函數(shù)轉(zhuǎn)變這些性屬):
????
- translationX,translationY:換轉(zhuǎn)標坐(control where the View is located as a delta from its left and top coordinates which are set by its layout container.)
- rotation,rotationX,rotationY:旋轉(zhuǎn),rotation用于2D旋轉(zhuǎn)角度,3D中用到后兩個
- scaleX,scaleY:縮放
- x,y:View的終最標坐(utility properties to describe the final location of the View in its container, as a sum of the left and top values and translationX and translationY values.)
- alpha:明透度
????
跟置位有關(guān)的參數(shù)有3個,以X標坐為例,可以通過getLeft(),getX(),getTranslateX()得獲,有若一Button btn2,局布時其標坐為(40,0): //應用動畫之前btn2.getLeft(); //40
btn2.getX(); //40
btn2.getTranslationX(); //0
//應用translationX動畫
ObjectAnimator oa=ObjectAnimator.ofFloat(btn2,"translationX", 200);
oa.setDuration(2000);
oa.start();
/*應用translationX動畫后
btn2.getLeft(); //40
btn2.getX(); //240
btn2.getTranslationX(); //200
*/
//應用X動畫,設(shè)假沒有應用之前的translationX動畫
ObjectAnimator oa=ObjectAnimator.ofFloat(btn2, "x", 200);
oa.setDuration(2000);
oa.start();
/*應用X動畫后
btn2.getLeft(); //40
btn2.getX(); //200
btn2.getTranslationX(); //160
*/ 無論怎樣應用動畫,本來的局布時的置位通過getLeft()得獲,持保變不;
????
X是View終最的置位;????
translationX為終最置位與局布時初始置位這差。????
所以若就用translationX即為在本來基礎(chǔ)上動移多少,X為終最多少????
getX()的值為getLeft()與getTranslationX()的和????
對于X動畫,源代碼是這樣的: case X:info.mTranslationX = value - mView.mLeft;
break;
Property Animation也可以在XML中定義
????
- <set> - AnimatorSet
- <animator> -?ValueAnimator
- <objectAnimator> -?ObjectAnimator
????
XML文件應放大/res/animator/中,通過以下方法應用動畫: AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator);set.setTarget(myObject);
set.start();
3.10 ViewPropertyAnimator
????如果要需對一個View的多個性屬停止動畫可以用ViewPropertyAnimator類,該類對多性屬動畫停止了優(yōu)化,合會并一些invalidate()來少減新刷視圖,該類在3.1中引入。
????以下兩段代碼實現(xiàn)樣同的效果:
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
?
myView.animate().x(50f).y(100f);文章結(jié)束給大家分享下程序員的一些笑話語錄: 問路
有一個駕駛熱氣球的人發(fā)現(xiàn)他迷路了。他降低了飛行的高度,并認出了地面 上的一個人。他繼續(xù)下降高度并對著那個人大叫,“打擾一下,你能告訴我我 在哪嗎?”
下面那個人說:“是的。你在熱氣球里啊,盤旋在 30 英尺的空中”。
熱氣球上的人說:“你一定是在 IT 部門做技術(shù)工作”。
“沒錯”,地面上的人說到,“你是怎么知道的?”
“呵呵”,熱氣球上的人說,“你告訴我的每件事在技術(shù)上都是對的,但對都沒 有用”。
地面上的人說,“你一定是管理層的人”。
“沒錯”,熱氣球上的人說,“可是你是怎么知道的?”
“呵呵”,地面上的那人說到,“你不知道你在哪里,你也不知道你要去哪,你 總希望我能幫你。你現(xiàn)在和我們剛見面時還在原來那個地方,但現(xiàn)在卻是我 錯了”。
轉(zhuǎn)載于:https://www.cnblogs.com/jiangu66/archive/2013/04/19/3031698.html
總結(jié)
以上是生活随笔為你收集整理的动画代码Android动画学习笔记动画代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十大不变计算机网络安全法则
- 下一篇: Linux 命令 查看监听端口