形狀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的專欄