Android: Bitmap/Canvas/Drawable
接觸到自定義View之後,經常會遇到Canvas與Paint, 從使用上不難理解Paint, 但是對於Canvas和Bitmap以及Drawable之間的關係不是很清楚. 今天看了下程式碼, 嘗試去區分一下.
Canvas
The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing). 複製程式碼
這個是Canvas類中寫的, 如果我們要繪製什麼的話, 需要:
- 一個Bitmap去持有畫素
- 一個Canvas來做主繪製呼叫, 並且繪製在Bitmap上
- 一個繪製原型, 比如矩形, path, text, Bitmap
- 一個畫筆, 用來描述繪製的顏色和樣式
從這裡我們就可以知道, 繪製呼叫是傳到Canvas裡, 但是繪製的位置是繪製在一個Bitmap上.
那麼Bitmap是啥呢?
Bitmap
點陣圖, 其實可以理解為int[] buffer
, 也就是說這裡有個快取, 用來儲存每個畫素的資訊
而Canvas類中有個Bitmap物件:
public class Canvas extends BaseCanvas { ... // may be null private Bitmap mBitmap; public Canvas(@NonNull Bitmap bitmap) { ... mBitmap = bitmap; ... } public void setBitmap(@Nullable Bitmap bitmap) { ... mBitmap = bitmap; } } 複製程式碼
因此實際繪製是繪製在Canvas所持有的Bitmap上
Drawable
Drawable是一個抽象, 描述所有可繪製的物件, 平時很少直接使用Drawable, 通常是使用drawable資源的方式獲取Drawable物件.
資源型別 | 檔案字尾 | Drawable型別 |
---|---|---|
Bitmap File | .png .jpg .gif | BitmapDrawable |
Nine-Patch File | .9.png | NinePatchDrawable |
Shape Drawable | .xml | ShapeDrawable |
State List | .xml | StateListDrawable |
與View的關係
public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { ... private Drawable mBackground; // 背景 ... public void setBackground(Drawable background) { setBackgroundDrawable(background); } @Deprecated public void setBackgroundDrawable(Drawable background) { ... mBackground = background; ... } public void draw(Canvas canvas) { ... // Step 1, draw the background, if needed if (!dirtyOpaque) { drawBackground(canvas); } ... } private void drawBackground(Canvas canvas) { final Drawable background = mBackground; ... background.draw(canvas); ... } @Override protected void onDraw(Canvas canvas) { } } 複製程式碼