Android中Drawable是一種可以在Canvas上進行繪制抽象的概念迈嘹,種類很多碰酝,常見的顏色和圖片都可以是一個Drawable丐黄。Drawable有很多種绊序,它們表示一種圖像的概念,但是它們又不全是圖片夸盟,通過顏色也可以構(gòu)造出各式各樣的圖像的效果蛾方。
Drawable的分類
- BitmapDrawable。它表示的就是一張圖片上陕,在實際開發(fā)中我們可以直接引用原始的圖片即可桩砰。
- ShapeDrawable∈筒荆可以理解為通過顏色來構(gòu)造圖形亚隅,可以有純色的圖形,也可以具有漸變效果的圖形庶溶。
- LayerDrawable煮纵。對應(yīng)的標簽是<Layer-list>,它表示一種層次化的Drawable集合渐尿,通過將不同的Drawable放置在不同的層上面從而達到一種疊加后的效果醉途。
- StateListDrawable。對應(yīng)于<Selector>砖茸,它表示Drawable集合,每個Drawable都對應(yīng)著View的一種狀態(tài)殴穴,這樣系統(tǒng)就會根據(jù)View的狀態(tài)來選擇合適的Drawable凉夯。
- LeveListDrawable。對應(yīng)于<level-list>標簽采幌,表示一個Drawable集合劲够,集合中的每個Drawable都有一個等級Level的概念。
- InsetDrawable休傍。對應(yīng)于<insert>標簽征绎,它可以將其他的Drawable內(nèi)嵌到自己當中,并可以在四周留出一定的間距磨取。
- ScaleDrawable人柿。對應(yīng)于<scale>,它可以根據(jù)自己的等級(level)將指定的Drawable縮放到一定比例忙厌。
- ClipDrawable凫岖。對應(yīng)于<clip>,它可以根據(jù)自己當前的等級(level)來裁剪另一個Drawable逢净,裁剪方向可以通過android:clipOrientation和android:gravity這兩個屬性來共同控制哥放。
Android動畫
Android的動畫可以分為三種:View動畫歼指、幀動畫和屬性動畫。View動畫通過對場景里的對象不斷做圖像變換(平移甥雕、縮放踩身、旋轉(zhuǎn)、透明度)從而產(chǎn)生動畫效果社露,它是一種漸近式動畫惰赋,并且View動畫支持自定義。幀動畫通過順序播放一系列圖像從而產(chǎn)生動畫效果呵哨,可以簡單理解為圖片切換動畫赁濒。屬性動畫通過動態(tài)地改變對象的屬性從而達到動畫效果,屬性動畫為API 11的新特性孟害,在低版本無法直接使用屬性動畫拒炎,但我們?nèi)匀豢梢酝ㄟ^兼容庫來使用它。
View動畫
View動畫的作用對象是View挨务,它支持平移動畫击你、縮放動畫、旋轉(zhuǎn)動畫和透明度動畫谎柄。有四個子類:TranslateAnimation丁侄,ScaleAnimation,RotateAnimation和AlphaAnimation朝巫『枰。可以通過XML來定義。比如:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator="true" >
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<translate
android:fromYDelta="500"
android:toXDelta="0" />
</set>
幀動畫
幀動畫是順序播放一組預(yù)先定義好的圖片劈猿,類似于電影播放拙吉。不同于View動畫,系統(tǒng)提供了另外一個類AnimationDrawable來使用幀動畫揪荣。雖然比較簡單筷黔,但是容易引起OOM,所以在使用幀動畫時應(yīng)盡量避免使用過多尺寸較大的圖片仗颈。
屬性動畫
屬性動畫中有ValueAnimator佛舱、ObjectAnimator和AnimatorSet等概念,通過它們可以實現(xiàn)絢麗的動畫挨决。屬性動畫可以對任意對象的屬性進行動畫而不僅僅是View请祖,動畫默認時間間隔300ms,默認幀率10ms/幀凰棉。在一個時間間隔內(nèi)完成對象從一個屬性值到另一個屬性值的改變损拢,因此屬性動畫幾乎是無所不能,只要對象有這個屬性撒犀,它都能實現(xiàn)動畫效果福压。
有個開源動畫庫:nineoldandroids來兼容之前的版本掏秩,因為屬性動畫是從API 11開始才有的。比較常用的動畫類ValueAnimator荆姆、ObjectAnimator和AnimatorSet蒙幻,其中ObjectAnimator繼承ValueAnimator,AnimatorSet是動畫集合胆筒,可以定義一組動畫邮破,它們使用起來也是極其簡單的。如何使用呢:
private void performAnimate(final View target, final int start, final int end) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
// 持有一個IntEvaluator對象仆救,方便下面估值的時候使用
private IntEvaluator mEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator animator) {
// 獲得當前動畫的進度值抒和,整型,1-100之間
int currentValue = (Integer) animator.getAnimatedValue();
Log.d(TAG, "current value: " + currentValue);
// 獲得當前進度占整個動畫過程的比例彤蔽,浮點型摧莽,0-1之間
float fraction = animator.getAnimatedFraction();
// 直接調(diào)用整型估值器通過比例計算出寬度,然后再設(shè)給Button
target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
target.requestLayout();
}
});
valueAnimator.setDuration(5000).start();
}
使用動畫注意點
- OOM問題顿痪。這個主要是出現(xiàn)在幀動畫中镊辕,當圖片數(shù)量較多且圖片較大時就極易出現(xiàn)OOM。
- 內(nèi)存泄漏蚁袭。在屬性動畫中有一類無限循環(huán)的動畫征懈,這類動畫需要在Activity退出時及時停止,否則將導致Activity無法釋放從而造成內(nèi)存泄漏揩悄,View動畫則并不存在此問題卖哎。
- 兼容性問題。動畫在3.0以下的系統(tǒng)上有兼容性問題虏束,在某些特殊場景可能無法正常工作棉饶,因此要做好適配問題。
- View動畫的問題镇匀。View動畫是對View的影像做動畫,并不是真正改變View的狀態(tài)袜啃,因此有時候會出現(xiàn)動畫完成后View無法隱藏的現(xiàn)象汗侵,即setVisibility(View.GONE)失效了,這個時候只要調(diào)用View.clearAnimation()清除View動畫即可解決此問題群发。
- 不要使用PX晰韵。在進行動畫的過程中,要盡量使用dp熟妓,使用px會導致在不同設(shè)備上有不同的效果雪猪。
- 動畫元素的交互。將View移動(平移)后起愈,在Android 3.0以前的系統(tǒng)上只恨,不管是View動畫還是屬性動畫译仗,新位置均無法觸發(fā)單擊事件,同時官觅,老位置仍然可以觸發(fā)單擊事件纵菌。盡管View已經(jīng)在視覺上不存在了,將View移回原位置以后休涤,原位置的單擊事件繼續(xù)生效咱圆。從3.0開始,屬性動畫的單擊事件觸發(fā)位置為移動后的位置功氨,但是View動畫仍然在原位置序苏。
- 硬件加速。使用動畫過程中捷凄,建議開啟硬件加速忱详,這樣會提高動畫的流暢性。