Android中Drawable是一種可以在Canvas上進行繪製抽象的概念,種類很多,常見的顏色和圖片都可以是一個Drawable。Drawable有很多種,它們表示一種影象的概念,但是它們又不全是圖片,通過顏色也可以構造出各式各樣的影象的效果。
Drawable的分類
- BitmapDrawable。它表示的就是一張圖片,在實際開發中我們可以直接引用原始的圖片即可。
- ShapeDrawable。可以理解為通過顏色來構造圖形,可以有純色的圖形,也可以具有漸變效果的圖形。
- LayerDrawable。對應的標籤是
,它表示一種層次化的Drawable集合,通過將不同的Drawable放置在不同的層上面從而達到一種疊加後的效果。 - StateListDrawable。對應於
,它表示Drawable集合,每個Drawable都對應著View的一種狀態,這樣系統就會根據View的狀態來選擇合適的Drawable。 - LeveListDrawable。對應於
標籤,表示一個Drawable集合,集合中的每個Drawable都有一個等級Level的概念。 - InsetDrawable。對應於
標籤,它可以將其他的Drawable內嵌到自己當中,並可以在四周留出一定的間距。 - ScaleDrawable。對應於
,它可以根據自己的等級(level)將指定的Drawable縮放到一定比例。 - ClipDrawable。對應於
,它可以根據自己當前的等級(level)來裁剪另一個Drawable,裁剪方向可以通過android:clipOrientation和android:gravity這兩個屬性來共同控制。
Android動畫
Android的動畫可以分為三種:View動畫、幀動畫和屬性動畫。View動畫通過對場景裡的物件不斷做影象變換(平移、縮放、旋轉、透明度)從而產生動畫效果,它是一種漸近式動畫,並且View動畫支援自定義。幀動畫通過順序播放一系列影象從而產生動畫效果,可以簡單理解為圖片切換動畫。屬性動畫通過動態地改變物件的屬性從而達到動畫效果,屬性動畫為API 11的新特性,在低版本無法直接使用屬性動畫,但我們仍然可以通過相容庫來使用它。
View動畫
View動畫的作用物件是View,它支援平移動畫、縮放動畫、旋轉動畫和透明度動畫。有四個子類: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>
幀動畫
幀動畫是順序播放一組預先定義好的圖片,類似於電影播放。不同於View動畫,系統提供了另外一個類AnimationDrawable來使用幀動畫。雖然比較簡單,但是容易引起OOM,所以在使用幀動畫時應儘量避免使用過多尺寸較大的圖片。
屬性動畫
屬性動畫中有ValueAnimator、ObjectAnimator和AnimatorSet等概念,通過它們可以實現絢麗的動畫。屬性動畫可以對任意物件的屬性進行動畫而不僅僅是View,動畫預設時間間隔300ms,預設幀率10ms/幀。在一個時間間隔內完成物件從一個屬性值到另一個屬性值的改變,因此屬性動畫幾乎是無所不能,只要物件有這個屬性,它都能實現動畫效果。
有個開源動畫庫: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();
// 直接呼叫整型估值器通過比例計算出寬度,然後再設給Button
target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
target.requestLayout();
}
});
valueAnimator.setDuration(5000).start();
}
使用動畫注意點
- OOM問題。這個主要是出現在幀動畫中,當圖片數量較多且圖片較大時就極易出現OOM。
- 記憶體洩漏。在屬性動畫中有一類無限迴圈的動畫,這類動畫需要在Activity退出時及時停止,否則將導致Activity無法釋放從而造成記憶體洩漏,View動畫則並不存在此問題。
- 相容性問題。動畫在3.0以下的系統上有相容性問題,在某些特殊場景可能無法正常工作,因此要做好適配問題。
- View動畫的問題。View動畫是對View的影像做動畫,並不是真正改變View的狀態,因此有時候會出現動畫完成後View無法隱藏的現象,即setVisibility(View.GONE)失效了,這個時候只要呼叫View.clearAnimation()清除View動畫即可解決此問題。
- 不要使用PX。在進行動畫的過程中,要儘量使用dp,使用px會導致在不同裝置上有不同的效果。
- 動畫元素的互動。將View移動(平移)後,在Android 3.0以前的系統上,不管是View動畫還是屬性動畫,新位置均無法觸發單擊事件,同時,老位置仍然可以觸發單擊事件。儘管View已經在視覺上不存在了,將View移回原位置以後,原位置的單擊事件繼續生效。從3.0開始,屬性動畫的單擊事件觸發位置為移動後的位置,但是View動畫仍然在原位置。
- 硬體加速。使用動畫過程中,建議開啟硬體加速,這樣會提高動畫的流暢性。
閱讀擴充套件
源於對掌握的Android開發基礎點進行整理,羅列下已經總結的文章,從中可以看到技術積累的過程。
1,Android系統簡介
2,ProGuard程式碼混淆
3,講講Handler+Looper+MessageQueue關係
4,Android圖片載入庫理解
5,談談Android執行時許可權理解
6,EventBus初理解
7,Android 常見工具類
8,對於Fragment的一些理解
9,Android 四大元件之 " Activity "
10,Android 四大元件之" Service "
11,Android 四大元件之“ BroadcastReceiver "
12,Android 四大元件之" ContentProvider "
13,講講 Android 事件攔截機制
14,Android 動畫的理解
15,Android 生命週期和啟動模式
16,Android IPC 機制
17,View 的事件體系
18,View 的工作原理
19,理解 Window 和 WindowManager
20,Activity 啟動過程分析
21,Service 啟動過程分析
22,Android 效能優化
23,Android 訊息機制
24,Android Bitmap相關
25,Android 執行緒和執行緒池
26,Android 中的 Drawable 和動畫
27,RecylerView 中的裝飾者模式
28,Android 觸控事件機制
29,Android 事件機制應用
30,Cordova 框架的一些理解
31,有關 Android 外掛化思考
32,開發人員必備技能——單元測試