Table of contents


這篇文章裡的原始碼我放在GITHUB上 : https://github.com/DraculaCwg/android_exercise

在android中,要設計出美觀的ui,通常都跟Drawable相關的物件脫離不了關係,Drawable翻成中文為”可繪的”,

drawable_101_001.png

由上面的類別結構圖可以得知,圖檔、顏色、動畫、圖形,漸層這些都是屬於Drawable的子類別。 回過頭來看所有gui元件的祖先View class,裡面跟Drawable有關的是setBackground開頭的幾個method, 也就是說,對於所有的元件,我們都可以透過圖片、形狀、顏色、…等Drawable的子類別來改變元件的外觀。

    public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
        public void setBackgroundColor(int color) {
            setBackgroundDrawable(new ColorDrawable(color));
        }
     
        public void setBackgroundColor(int color) {
           ...
        }
     
        @RemotableViewMethod
        public void setBackgroundResource(int resid) {
            if (resid != 0 && resid == mBackgroundResource) {
                return;
            }
     
            Drawable d= null;
            if (resid != 0) {
                d = mResources.getDrawable(resid);
            }
            setBackgroundDrawable(d);
     
            mBackgroundResource = resid;
        }
     
        public void setBackgroundDrawable(Drawable d) {
            ...
        }
    }

實務上比較常用的做法,是透過xml來設定元件的background,而官網文件上的Drawable Resources 裡面的xml tag都可以找到跟上面的類別相對應的tag,需要特別注意的是 .png, .9.png,.jpg, or .gif這些圖檔只要放在res\drawable的目錄下,就會自動依檔名變成可以直接在XML裡引用的Drawable Resource,不需額外的tag 而另外常用的還有Shape Drawable這種resource,他裡面包含了處理顏色、形狀,外框的子tags

基本上,只要透過圖片跟Shape Drawable,就可以玩出很多效果了,先從簡單的來好了:

圖片

要改變元件的外觀,最快的方式就是把元件加上背景圖片,下圖效果都是單純的把元件的背景圖片換掉而已

drawable_101_002.png

上圖三個view,分別是用這三個圖片當底圖 (圖片來源 : http://www.dibbus.com/2011/03/9patch-images-in-android/)

drawable_101_003.png drawable_101_004.png drawable_101_005.png

透過把android:background設定成圖片的resource就可以達到上面的效果

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <TextView
        android:id="@+id/bule"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@drawable/btn_blue_matte"
        android:gravity="center"
        android:text="bule"
        android:textColor="@color/White" />
 
    <TextView
        android:id="@+id/bule_glossy"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@drawable/btn_blue_glossy"
        android:gravity="center"
        android:text="bule glossy"
        android:textColor="@color/White" />
 
    <TextView
        android:id="@+id/corner"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@drawable/btn_blue_pink_glossy"
        android:gravity="center"
        android:text="blue glossy with pink"
        android:textColor="@color/White" />
 
</LinearLayout>

Shape Drawable

除了用圖片,也可以用Shape Drawable的方式來改變元件的外觀,Shape Drawable可以運用的tag如下

  1. <corners> 圖形的四個角的形狀
  2. <gradient> 漸層
  3. <padding> 內部圖文
  4. <size>
  5. <solid> 填滿的顏色
  6. <stroke> 外框的線條效果

下面就是透過設定Shape Drawable的tag達到的效果

  1. 第一個view是使用了數個子tag達到的
  2. 第二個view是只使用<gradient>做漸層
  3. 第三個view是只使用<corners>來設定圖形為圓角(round)
  4. 第四個view是只使用<solid>設定背景為綠色
  5. 第五個view是只使用<stroke>來設定外框的效果

drawable_101_006.png

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
     
        <TextView
            android:id="@+id/all"
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:gravity="center"
            android:background="@drawable/shape_all"
            android:textColor="@color/Black"
            android:text="shape mix" />
     
        <TextView
            android:id="@+id/gradient"
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:gravity="center"
            android:background="@drawable/shape_gradient"
            android:textColor="@color/Black"
            android:text="gradient" />
     
        <TextView
            android:id="@+id/corner"
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:gravity="center"
            android:background="@drawable/shape_corners"
            android:textColor="@color/Black"
            android:text="corner" />
     
     
        <TextView
            android:id="@+id/corner"
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:gravity="center"
            android:background="@drawable/shape_solid"
            android:textColor="@color/Black"
            android:text="corner" />
        <TextView
            android:id="@+id/stroke"
            android:layout_width="match_parent"
            android:layout_height="75dp"
            android:gravity="center"
            android:background="@drawable/shape_stroke"
            android:textColor="@color/White"
            android:text="stroke" />
     
    </LinearLayout>

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <gradient
            android:centerColor="@color/WhiteSmoke"
            android:endColor="@color/Yellow"
            android:startColor="@color/Blue" />
        <corners android:radius="50dp" />
        <stroke
            android:dashGap="5dp"
            android:dashWidth="3dp"
            android:width="5dp"
            android:color="@color/DarkSalmon" />
    </shape>

漸層
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
     
        <gradient
            android:angle="90"
            android:centerColor="@color/WhiteSmoke"
            android:endColor="@color/Yellow"
            android:startColor="@color/Blue" />
     
    </shape>

圓角
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <corners android:radius="50dp"/>
        <solid android:color="@color/White"/>
    </shape>

背景色
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
     
        <solid android:color="@color/Green" />
     
    </shape>

外框
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <stroke android:width="5dp"
            android:color="@color/Red"
            android:dashWidth="3dp"
            android:dashGap="5dp"
            />
    </shape>

半透明效果

像下圖的半透明效果(Smoked Glass),可以直接透過設定backgroud的顏色的透明度來達到,

drawable_101_007.png

上圖的效果,主要就是在下面的這張圖上,放了一個半透明的text view,要讓view半透明就是設定View的backgroud屬性,android:background=”#77000000” #77000000是傳統的RGB前面加上一個透明度(alpha),以傳統的RGB值#000000是全黑,#FFFFFF是全白,而前面的alpha的值也是00~FF,這邊設成77剛好是一半。

[[android:drawable_101_008.png][]

    <?xml version="1.0" encoding="utf-8"?>
     
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/frameLayout1"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@drawable/google_doodle" >
     
        <TextView
            android:id="@android:id/text2"
            android:layout_width="fill_parent"
            android:layout_height="100dp"
            android:background="#77000000"
            android:gravity="center_vertical"
            android:text="smoked glass"
            android:textColor="#ffffffff"
            android:textSize="30dip" />
     
    </FrameLayout>

透明度的效果好不好,會跟後面的背景有關,有時,同一個透明度的值,在不同的背景下,效果就會差很多

Resource