如何了解Bitmap、View、Drawable、Canvas以及Paint的差異

如何了解Bitmap、View、Drawable、Canvas以及Paint的差異

常常搞不清楚這幾個元件的差異,
後來找了許多資料, 釐清相關的功能,
總算稍微搞懂這些元件的相關性,
雖然我要講的是View、Drawable、Canvas以及Paint的差異,

但是其實大家常常也把Bitmap搞混, 所以我把這個加進來做一些解釋。

Bitmap指的是你今天有一張圖片存在電腦,
它的格式可能是bmp, jpg, png或者gif, 常看到的是這幾個,
而Android剛好也支援這幾個, 因此我們可以用Bitmap這個類別的物件,
將我們的圖檔讀進Android, 通常讀進去以後它就變成串流模式(Stream),
為什麼呢? 很簡單, 因為電腦看不懂圖片, 只認得二進制碼,
所以我們打成串流才可以讓電腦了解我們的圖是什麼東西。

先來講個View好了, View你可以想像成一種容器, 它可以用來裝你的Bitmap,
根據你事先排好的格式, 然後呈現在畫面上,
那系統因應user的需求, 也制定了一些需要的View容器給大家來使用,
例如ImageView、GridView、ListView、Button、EditText…等等。

例如GridView就像我們熟知的九宮格排列, 每一個格子就是一個View,
而這個容器可以讓使用者動態的一直增加View,
至於View裡面的排列就由使用者來決定。

那如果我們想要自定自己的容器呢? 當然可以, 不過先別急,
先來了解什麼是Canvas,
Canvas就是一張畫布, 上面可以讓你畫你想畫的東西,
你可以想像成他就是小畫家工具,
你想畫一條線, 一個矩形, 蒙娜麗莎…等等,都可以。

那畫完以後怎麼辦? 很簡單, 把它裝到容器裡面,
容器有哪些?
就是我們前面講的ImageView、GridView、ListView…等等, 就是系統幫我們做好的容器,
不過這次是存成屬於自己的View, 講白話一點就是把我們畫的東西包成一個容器,
容器裡面裝的是我們的畫布。

接下來就是Drawable了, 有時候我們會想要畫矩形, 畫圓形或者畫弧形之類的,
而如果是自己用手畫, 很容易, 但是如果是用程式畫,
你就必須自己設定角度、長度、大小、顏色等屬性,
這些步驟有點麻煩, 因此通常都會設定好一個框架讓你使用,
只需要你指定屬性值, Android就會幫你設計好, 不用在自己設計一套,
例如Drawable的子類別ShapeDrawable就可以幫你完成許多圖形,
ArcShape, OvalShape, RectShape…等等。
當然不止ShapeDrawable, 還有

Known Direct Subclasses
BitmapDrawable, ClipDrawable, ColorDrawable, DrawableContainer, GradientDrawable,
InsetDrawable, LayerDrawable,NinePatchDrawable, PictureDrawable, RotateDrawable,
ScaleDrawable, ShapeDrawable
Known Indirect Subclasses
AnimationDrawable, LevelListDrawable, PaintDrawable, StateListDrawable, TransitionDrawable


超多Drawable可以直接使用的。

寫個例子

public class CustomDrawableView extends View{
    private ShapeDrawable mDrawable;
    private Paint mPaint;
    private int x = 0;
    private int y = 0;
    private int width = 100;
    private int height = 50;
    public CustomDrawableView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        mDrawable = new ShapeDrawable(new RectShape());
        mDrawable.setBounds(x,y,x+width,y+height);

        mPaint = mDrawable.getPaint();
        mPaint.setColor(Color.BLUE);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        mDrawable.draw(canvas);
    }
}

上面就是利用RectShape來完成矩形的模式,
之後利用ShapeDrawable的draw物件來畫在Canvas物件(畫布)上面,
由於這是在繼承View之下完成的, 因此它就直接包成一個View容器。

所以接著你就可以把這個CustomDrawableView視為跟ImageView一樣的元件來使用。
我們也可以把圖片轉成BitmapDrawable以後, 貼到畫布上面。

那畫好以後, 每個Drawable都會有一個draw的方法, 它就是會幫你把這些圖形貼到畫布上面,
然後再裝到自定的容器View裡面, 最後就變成一種容器,
看你是要裝進系統的容器或者直接呈現出來都可以。

最後一個是Paint了, Paint就是畫筆, 你在小畫家上面畫畫的時候,
都會選擇畫筆來作畫, 像什麼顏色啊, 粗細啊之類的屬性,
像上面的例子當中, 我們取得Drawable的畫筆, 然後將畫筆的顏色改成藍色,
這樣畫出來的顏色就會變成藍色的矩形了。

那是畫在哪邊? 當然是畫布上面,
通常Paint都會跟在Drawable的相關類別或者自定View類別一起使用。

這樣大致上就把這些關係都講完了。