形狀Drawable
當你想動態畫2維圖形,ShapeDrawable對象是可能是你合適的選擇.使用ShapeDrawable,你可以隨意畫出原始的形狀並且應用到任何風格.
ShapeDrawable是一個Drawable的派生類,所以你可以用於任何想使用Drawable的地方—比如可能是一個View的背景,通過setBackgroundDrawable()所設置.當然,你也可以把你的形狀作為它自己的自定義View繪制,然後以你喜歡的方式添加到你的Layout.因為ShapeDrawable有它自己的draw()方法,你可以創建一個View的子類然後在View.onDraw()的方法中畫這個ShapeDrawable.下面是一個簡單的View派生類,它僅把ShapeDrawable當作一個View繪出:
[java] public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
public CustomDrawableView(Context context) {
super(context);
int x = 10;
int y = 10;
int width = 300;
int height = 50;
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
public CustomDrawableView(Context context) {
super(context);
int x = 10;
int y = 10;
int width = 300;
int height = 50;
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
在構造函數中,以OvalShape定義瞭一個ShapeDrawable.然後給它設置瞭顏色和形狀的邊界.如果你不設置邊界,形狀是不會被畫出的,如果你不設置顏色,將以黑色畫之.
使用自定義View,你可以畫任何東西.在上面的例子中,我們可以在一個Activity中用程序隨意作畫:
[java] CustomDrawableView mCustomDrawableView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCustomDrawableView = new CustomDrawableView(this);
setContentView(mCustomDrawableView);
}
CustomDrawableView mCustomDrawableView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCustomDrawableView = new CustomDrawableView(this);
setContentView(mCustomDrawableView);
}
如果你想在XMLlayout中畫這個自定義drawable而不是在Activity中,那麼這個CustomDrawableView類必須重寫View(Context,AttributeSet)構造方法,此方法在從XML初始化一個View時被調用.然後添加一個CustomDrawable元素到XML,像這樣:
[html] <com.example.shapedrawable.CustomDrawableView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<com.example.shapedrawable.CustomDrawableView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
ShapeDrawable類(就像android.graphics.drawable包中的其它一些Drawable類型)允許你使用公開方法來定義drawable的各種屬性.你要調整的一些屬性可能有alpha透明,顏色過慮,抖動,opacity和color等.
你也可以使用XML定義原始的drawable形狀.更多的信息請看Drawable資源文檔中的ShapeDrawables章節.
九宮格NinePatch
一個NinePatchDrawable圖形是一個可拉申的位圖,在把它作為View的背景時,Android自動把它的大小拉伸來適應View的內容.一個例子就是標準按鈕使用NinePatch作為自己的背景— 按鈕必須能被拉申來適應文本的長度.NinePatchdrawable是一個標準的PNG圖像,但它包含瞭一個額外的1像素寬的邊框.它必須保存為.9.png這樣的擴展名,並且放在你的工程的res/drawable/文件夾下.
邊框被用來定義圖像的可拉伸區和靜態區.你通過在上邊框和左邊框畫1個(或多個)1像素寬的黑線來表明可伸縮區域(其它邊框部分需保持完全透明或白色).你可以設定任意數量的可伸縮段:它們的相對大小不變,所以最大的段總是保持最大.
你也可以通過在右邊框和下邊框畫線來定義一個圖像的可選的可繪制段(實際上,叫做填充線段).如果一個View對象設置瞭NinePatch作為背景然後又指定瞭自己的文本,它將拉伸自己以使所有的文本恰好處於被右和下的線段所指定的區域內.如果填充線段不存在,Android使用左和上的線段來定義這個可繪制區域.
左和上的線段定義瞭圖像的哪些像素可以在拉伸時被復制;下和右的線段定義瞭圖像的內容應被放入的區域,這些區域的位置都是相對的.
下面是一個用NinePatch文件定義一個按鈕的例子:
這個NinePatch用上和左線段定義瞭一個可拉伸區域並用右和下線段定義瞭可繪制區域.在第一個圖中,灰色虛線表明瞭拉伸時要被復制的區域,紅色框表明瞭View的內容應在的區域.如果內容不適合這個區域,那麼圖像將被拉伸直到能適合.
畫9-patch的工具提供瞭一個極順手的方式來創建你的NinePatch圖像,它有一個WYSIWYG圖像編輯器.如果你定義的可拉伸區域有產生像素復寫的風險時,它甚至會發出警告.
XML例子
下面是一個 layoutXML例子來演示如何添加一個NinePatch圖像到一對按鈕中.(NinePatch圖像被保存為res/drawable/my_button_background.9.png)
[html] <Button id="@+id/tiny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:text="Tiny"
android:textSize="8sp"
android:background="@drawable/my_button_background"/>
<Button id="@+id/big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:text="Biiiiiiig text!"
android:textSize="30sp"
android:background="@drawable/my_button_background"/>
<Button id="@+id/tiny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:text="Tiny"
android:textSize="8sp"
android:background="@drawable/my_button_background"/>
<Button id="@+id/big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:text="Biiiiiiig text!"
android:textSize="30sp"
android:background="@drawable/my_button_background"/>
註意width和height被設置為"wrap_content"使得按鈕能恰好包含文本.
下圖是兩個從XML和and上面所顯示的NinePatch圖像所畫出的按鈕.註意按鈕的寬和高如何跟據文本而變化,以及背景圖如何拉伸以適應它.
摘自 nkmnkm的專欄