圖文詳解Andorid中用Shape定義GradientDrawable

Android中提供了各種類型的Drawable,也可以用XML定義各種Drawable。本文重點講述如何用XML中的shape節點定義GradientDrawable。

用XML定義的drawable文件放在res/drawable目錄下。

用XML文件定義GradientDrawable的語法如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<shape
    android:shape=["rectangle" | "oval" | "line" | "ring"] >
    <corners
        android:radius="integer"
        android:topLeftRadius="integer"
        android:topRightRadius="integer"
        android:bottomLeftRadius="integer"
        android:bottomRightRadius="integer" />
    <gradient
        android:angle="integer"
        android:centerX="integer"
        android:centerY="integer"
        android:centerColor="integer"
        android:endColor="color"
        android:gradientRadius="integer"
        android:startColor="color"
        android:type=["linear" | "radial" | "sweep"]
        android:useLevel=["true" | "false"] />
    <padding
        android:left="integer"
        android:top="integer"
        android:right="integer"
        android:bottom="integer" />
    <size
        android:width="integer"
        android:height="integer" />
    <solid
        android:color="color" />
    <stroke
        android:width="integer"
        android:color="color"
        android:dashWidth="integer"
        android:dashGap="integer" />
</shape>

該文件以<shape>爲根結點,其shape屬性可取四種值:rectangle、oval、line或ring。以上語法格式中雖然列出了很多屬性,但是並不是對於所有類型的shape都支持這些屬性。下面分別對這四種shape進行講解。

rectangle

在res/drawable下面用XML文件定義了一個名爲rectangle的GradientDrawable,其對應的shape值爲rectangle,表明我們定義的drawable的形狀是矩形。在layout文件中定義了一個TextView,其使用了上述drawable,如下所示:

1
2
3
4
<TextView android:text="@string/hello_world"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:background="@drawable/rectangle" />
  • solidrectangle.xml定義如下所示:
    1
    2
    3
    4
    5
    <?xml version="1.0" encoding="utf-8"?>
    android:shape="rectangle">
        <solid android:color="#00ff00" />
    </shape>

    在上面的XML文件中,我們將shape屬性設置爲rectangle,我們將<solid>節點的color屬性設置爲綠色,<solid>屬性是用來設置面的填充色的,效果如下所示:
    這裏寫圖片描述

  • corners
    <corners>節點用於設置drawable四個拐角的半徑,對應的XML文件如下所示:
    1
    2
    3
    4
    5
    6
    <?xml version="1.0" encoding="utf-8"?>
    android:shape="rectangle">
        <solid android:color="#00ff00" />
        <corners android:radius="20dp" />
    </shape>

    效果如下所示:
    這裏寫圖片描述只有當shape屬性值爲rectangle時,<corners>節點纔會有用。<corners>節點的radius屬性同時定義了四個角的半徑,如果想讓這四個角的半徑不一樣,可以分別設置topLeftRadius、topRightRadius、bottomLeftRadius和bottomRightRadius屬性,不過在設置這四個屬性之前應先設置radius屬性作爲默認值,且默認值要大於1,無法正常使用其他四個屬性。

  • padding
    <padding>節點用於設置drawable的padding,可以分別設置left、right、top、bottom四個屬性,其作用與直接對TextView設置的四個paddingLeft、paddingRight、paddingTop、paddingBottom屬性等價。XML文件如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="utf-8"?>
    android:shape="rectangle">
        <solid android:color="#00ff00" />
        <corners android:radius="20dp" />
        <padding android:left="10dp"
            android:right="10dp"
            android:top="10dp"
            android:bottom="10dp" />
    </shape>

    效果如下所示:
    這裏寫圖片描述

  • size
    可以用<size>節點的width和height屬性設置drawable的尺寸。默認情況下,用<shape>定義的drawable會自動縮放到包含drawable的View尺寸範圍。比如我們有如下的ImageView的src設置了<shape>定義的drawable,當我們設置了其scaleType值爲center時,<shape>中定義的size尺寸就會限制drawable縮放。定義的ImageView如下所示:
    1
    2
    3
    4
    5
    6
    <ImageView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:src="@drawable/rectangle"
        android:scaleType="center"
        />

    對應的drawable定義如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    <?xml version="1.0" encoding="utf-8"?>
    android:shape="rectangle">
        <solid android:color="#00ff00" />
        <corners android:radius="20dp" />
        <size android:width="100dp"
            android:height="100dp" />
    </shape>

    效果如下所示:
    這裏寫圖片描述

  • stroke
    可以用<stroke>節點設置drawable的輪廓線,通過width屬性設置輪廓線的寬度,通過color屬性設置輪廓線的顏色。默認情況下,<stroke>定義的是實線,除此之外,還可以設置dashWidthdashGap屬性,如果設置了這兩個屬性,那麼就是虛線。其中,dashWidth定義了每個虛線段的長度,dashGap定義了兩個虛線段之間的距離。對應的XML文件如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version="1.0" encoding="utf-8"?>
    android:shape="rectangle">
        <solid android:color="#00ff00" />
        <corners android:radius="20dp" />
        <padding android:left="20dp"
            android:top="20dp"
            android:right="20dp"
            android:bottom="20dp" />
        <stroke android:width="1dp"
            android:color="#0000ff"
            android:dashWidth="8dp"
            android:dashGap="2dp" />
    </shape>

    效果如下所示:
    這裏寫圖片描述

  • gradient
    上面我們說到,通過<solid>可以設置drawable的顏色,但是隻是一種純色,如果想讓drawable產生漸變效果,可以使用<gradient>節點創建漸變色效果。<gradient>節點具有以下屬性:type、startColor、centerColor、endColor、angle、centerX、centerY、gradientRadius。其中type有三種取值:linear、radial和sweep,默認值是linear。當type取不同的值時,<gradient>並不是支持全部屬性,下面詳細說明。
    • linear
      <gradient>的type值爲linear時,表示顏色是線性漸變的,此時支持startColor、centerColor、endColor、angle這四個屬性,其他屬性不支持。我們可以通過設置startColor和endColor指定漸變的起始顏色以及終止顏色,XML如下所示:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="linear"
              android:startColor="#ff0000"
              android:endColor="#0000ff" />
      </shape>

      我們將startColor設置爲紅色,endColor設置爲藍色,效果如下所示:
      這裏寫圖片描述我們還可以設置centerColor屬性,指定中間色,XML如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" /&gt;
          <gradient android:type="linear"
              android:startColor="#ff0000"
              android:centerColor="#00ff00"
              android:endColor="#0000ff" />
      </shape>

      我們將中間色設置爲綠色,效果如下所示:
      這裏寫圖片描述

      默認情況下,漸變是從左向右進行的,如果想調整漸變的方向可以設置angle屬性,angle的默認值爲0,對應着自左向右漸變,angle的單位是角度,angle的值必須是45的倍數,否則不會有漸變效果。我們可以更改angle值,XML如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="linear"
              android:startColor="#ff0000"
              android:centerColor="#00ff00"
              android:endColor="#0000ff"
              android:angle="90" />
      </shape>

      我們將angle設置爲90度,那麼漸變方向就變成了從下上,效果如下所示:
      這裏寫圖片描述

    • radial
      <gradient>的type值爲radial時,表示顏色從某點向周圍輻射漸變,此時支持除angle之外的其他所有屬性。我們必須通過設置gradientRadius屬性以指定漸變的輻射半徑,通過startColor指定起始顏色,XML如下所示:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="radial"
              android:gradientRadius="50dp"
              android:startColor="#ff0000" />
      </shape>

      我們將startColor設置爲紅色,效果如下所示:
      這裏寫圖片描述由上圖我們可以發現,startColor(紅色)從中心沿着圓的半徑逐漸變淡。

      在設置了startColor的基礎上,我們還可以設置centerColor,XML如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle"&gt;
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="radial"
              android:gradientRadius="50dp"
              android:startColor="#ff0000"
              android:centerColor="#00ff00" />
      </shape>

      效果如下圖所示:
      這裏寫圖片描述

      由上圖可以看出,startColor(紅色)從中心沿着圓的半徑逐漸漸變到centerColor(綠色)。

      除了設置startColor、centerColor,還可以設置endColor,XML如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="radial"
              android:gradientRadius="50dp"
              android:startColor="#ff0000"
              android:centerColor="#00ff00"
              android:endColor="#0000ff" />
      </shape>

      我們將centerColor設置爲綠色,效果如下所示:
      這裏寫圖片描述
      由上圖可以看出,startColor(紅色)從中心沿着圓的半徑逐漸漸變到centerColor(綠色),在指定的半徑之外顏色用endColor(藍色)填充。

      其實,startColor、centerColor、endColor這三個屬性可以任意組合,大家可以自己嘗試一下各種組合的效果。

      默認圓心的位置處於drawable的中心,我們可以通過centerX和centerY屬性改變漸變圓心的位置,centerX和centerY的取值範圍都是0到1,這兩個屬性的默認值都是0.5,drawable的左上角的centerX和centerY的值都是0,右下角的centerX和centerY的值都是1。我們改變centerX和centerY的值,XML如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="radial"
              android:gradientRadius="50dp"
              android:startColor="#ff0000"
              android:centerColor="#00ff00"
              android:endColor="#0000ff"
              android:centerX="0"
              android:centerY="0.5" />
      </shape>

      效果如下所示:
      這裏寫圖片描述

    • sweep
      <gradient>的type值爲sweep時,表示顏色是圍繞中心點360度順時針旋轉的,起點就是3點鐘位置。
      我們可以只設置startColor,XML文件如下所示:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="sweep"
              android:startColor="#ff0000" />
      </shape>

      我們將startColor設置爲紅色,效果如下所示:
      這裏寫圖片描述我們也可以只設置endColor,XML文件如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="sweep"
              android:endColor="#0000ff" />
      </shape>

      將endColor設置爲藍色,效果如下所示:
      這裏寫圖片描述

      我們也可以只設置centerColor的值,XML文件如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="sweep"
              android:centerColor="#00ff00" />
      </shape>

      將centerColor設置爲綠色,效果如下所示:
      這裏寫圖片描述

      我們也可以同時設置startColor、centerColor、endColor的值,XML文件如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="sweep"
              android:startColor="#ff0000"
              android:centerColor="#00ff00"
              android:endColor="#0000ff" />
      </shape>

      將startColor、centerColor、endColor分別設置爲紅、綠、藍,效果如下所示:
      這裏寫圖片描述

      centerX和centerY的默認值都是0.5,表示中心點的默認位置就是drawable的中心,我們也可以更改centerX和centerY的值,從而更新中心點的位置,XML文件如下所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      <?xml version="1.0" encoding="utf-8"?>
      android:shape="rectangle">
          <corners android:radius="20dp" />
          <padding android:left="20dp"
              android:top="20dp"
              android:right="20dp"
              android:bottom="20dp" />
          <gradient android:type="sweep"
              android:startColor="#ff0000"
              android:centerColor="#00ff00"
              android:endColor="#0000ff"
              android:centerX="0.25"
              android:centerY="0.5" />
      </shape>

      我們將centerX的值設置爲0.25,效果如下所示:
      這裏寫圖片描述

oval

在res/drawable下面用XML文件定義了一個名爲oval的GradientDrawable,其對應的shape值爲oval,表示drawable的形狀是橢圓,並將該drawable作爲TextView的background。oval和rectangle的主要區別就是drawable的形狀不同,大部分的節點屬性的作用是相同的。

  • solid
    如同rectangle,我們可以通過solid指定drawable的顏色,XML如下所示:
    1
    2
    3
    4
    5
    <?xml version="1.0" encoding="utf-8"?>
        android:shape="oval">
        <solid android:color="#00ff00" />
    </shape>

    效果如下所示:
    這裏寫圖片描述

  • corners
    當shape爲oval時,不支持<corners>節點。
  • padding
    oval同樣支持<padding>節點,將四個padding值設置爲20dp,效果如下所示:
    這裏寫圖片描述
  • size
    oval不支持<size>節點。
  • stroke
    同rectangle一樣,我們也可以爲oval設定<stroke>,效果如下所示:
    這裏寫圖片描述
  • gradient
    oval同樣支持<gradient>節點實現漸變效果,type屬性也是支持linear、radial、sweep三個屬性。<gradient>節點實現的漸變效果桶rectangle的漸變效果基本一樣。
    • linear
      當type爲linear時,實現線性漸變效果,我們將startColor、centerColor、endColor分別設置爲紅、綠、藍,並設置angle爲45度,效果如下所示:
      這裏寫圖片描述
    • radial
      當type爲radial時,實現放射漸變效果,我們將startColor、centerColor、endColor分別設置爲紅、綠、藍,效果如下所示:
      這裏寫圖片描述
    • sweep
      當type爲sweep時,表示顏色是圍繞中心點360度順時針旋轉的,起點就是3點鐘位置。我們將startColor、centerColor、endColor分別設置爲紅、綠、藍,效果如下所示:
      這裏寫圖片描述<gradient>節點中的多個參數組合的效果可以參見上述rectangle中的說明。

line

在res/drawable下面用XML文件定義了一個名爲line的GradientDrawable,其對應的shape值爲line,並將該drawable作爲TextView的background。當shape爲line時,表示drawable的形狀是線,該線會分割drawable。line只支持<stroke><padding>兩個節點,不支持其他的節點。

XML文件如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
    android:shape="line">
    <stroke android:color="#0000ff"
        android:width="1dp"
        android:dashWidth="8dp"
        android:dashGap="2dp" />
    <padding android:left="20dp"
        android:right="20dp"
        android:top="20dp"
        android:bottom="20dp" />
</shape>

效果如下所示:
這裏寫圖片描述

ring

在res/drawable下面用XML文件定義了一個名爲ring的GradientDrawable,其對應的shape值爲ring,表示drawable的形狀是圓環,並將該drawable作爲TextView的background。所謂圓環就是大圓套小圓。當shape爲ring時,shape有額外的四個屬性可用:innerRadius、thickness、innerRadiusRatio、thicknessRatio。

需要特別注意的是,在API<=19的真機上使用shape爲ring的drawable時,Android有個bug,會不顯示drawable,解決辦法是將shape設置useLevel屬性爲true。

我們通過innerRadius指定小圓的半徑,通過thickness指定大圓和小圓之間的寬度。XML如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
    android:shape="ring"
    android:innerRadius="10dp"
    android:thickness="20dp"
    android:useLevel="false">
    <solid android:color="#00ff00" />
    <padding android:left="20dp"
        android:right="20dp"
        android:top="20dp"
        android:bottom="20dp" />
</shape>

效果如下所示:
這裏寫圖片描述

我們還可以通過innerRadiusRatio指定小圓的半徑,innerRadiusRatio的值是float類型,如果其值是9,表示小圓的半徑等於TextView寬度的1/9。同樣,也可以通過thicknessRatio指定大圓和小圓之間的寬度,其值類型也是float,如果值爲8,則表示大小圓之間的寬度等於TextView的1/8。XML文件如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
    android:shape="ring"
    android:innerRadiusRatio="9"
    android:thicknessRatio="8"
    android:useLevel="false">
    <solid android:color="#00ff00" />
    <padding android:left="20dp"
        android:right="20dp"
        android:top="20dp"
        android:bottom="20dp" />
</shape>

效果如下所示:
這裏寫圖片描述

如果給ring設置了<stroke>,那麼大小圓都會使用該設置的輪廓線,效果如下所示:
這裏寫圖片描述

ring同樣支持<gradient>實現漸變效果,默認type爲linear,只將startColor設置爲紅色,效果如下所示:
這裏寫圖片描述

type爲linear時,只將centerColor設置爲綠色,效果如下所示:
這裏寫圖片描述

type爲linear時,只將endColor設置爲藍色,效果如下所示:
這裏寫圖片描述

type爲linear時,<gradient>也支持angle參數。大家可以自己嘗試多種顏色的組合效果。

<gradient>的type值設置爲gradial時,需要指定gradientRadius屬性,否則會報錯。gradial並不能像上面那樣實現輻射漸變效果,gradial的ring只是用startColor填充圓環的顏色,實現的效果與指定<solid>節點中的color屬性相同,此處就不貼圖了。

當type爲sweep時,表示顏色是圍繞中心點360度順時針旋轉的,起點就是3點鐘位置。我們將startColor、centerColor、endColor分別設置爲紅、綠、藍,效果如下所示:
這裏寫圖片描述

轉自:Android開發中文站 » 圖文詳解Andorid中用Shape定義GradientDrawable
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章