Android-Xml繪圖
Android XML繪圖
XMl在Android中可不僅僅是一個布局檔案、配置列表。它甚至可以變成一張畫、一張圖。
Bitmap
聲明:
res/drawable/bitmap.xml
引用
Shape
android的樣式主要則是通過shape、selector、layer-list、level-list、style、theme等組合實現。
一般用shape定義的xml檔案存放在drawable目錄下,若項目沒有該目錄則建立一個,而不要將它放到drawable-hdpi等目錄中。
使用shape可以自訂形狀,可以定義下面四種類型的形狀,通過android:shape屬性指定:
rectangle: 矩形,預設的形狀,可以畫出直角矩形、圓角矩形、弧形等 oval: 橢圓形,用得比較多的是畫正圓 line: 線形,可以畫實線和虛線 ring: 環形,可以畫環形進度條
通過shape可以在XML中繪製任何形狀,下面展示了Shape所支援的參數
rectangle
solid: 設定形狀填充的顏色,只有android:color一個屬性
android:color 填充的顏色
padding: 設定內容與形狀邊界的內間距,可分別設定左右上下的距離
android:left 左內間距android:right 右內間距android:top 上內間距android:bottom 下內間距
gradient: 設定形狀的漸層顏色,可以是線性漸層、輻射漸層、掃描性漸層
android:type 漸層的類型 linear 線性漸層,預設的漸層類型 radial 放射漸層,設定該項時,android:gradientRadius也必須設定 sweep 掃描性漸層android:startColor 漸層開始的顏色android:endColor 漸層結束的顏色android:centerColor 漸層中間的顏色android:angle 漸層的角度,線性漸層時才有效,必須是45的倍數,0表示從左至右,90表示從下到上android:centerX 漸層中心的相對X座標,放射漸層時才有效,在0.0到1.0之間,預設為0.5,表示在正中間android:centerY 漸層中心的相對X座標,放射漸層時才有效,在0.0到1.0之間,預設為0.5,表示在正中間android:gradientRadius 漸層的半徑,只有漸層類型為radial時才使用android:useLevel 如果為true,則可在LevelListDrawable中使用
corners: 設定圓角,只適用於rectangle類型,可分別設定四個角不同半徑的圓角,當設定的圓角半徑很大時,比如200dp,就可變成弧形邊了
android:radius 圓角半徑,會被下面每個特定的圓角屬性重寫android:topLeftRadius 左上方的半徑android:topRightRadius 右上方的半徑android:bottomLeftRadius 左下角的半徑android:bottomRightRadius 右下角的半徑
stroke: 設定描邊,可描成實線或虛線。
android:color 描邊的顏色android:width 描邊的寬度android:dashWidth 設定虛線時的橫線長度android:dashGap 設定虛線時的橫線之間的距離
接著在要使用的view裡引用就可以了,例如本例中用做TextView的background:
:
全部:
oval
oval用來畫橢圓,而在實際應用中,更多是畫正圓,比如訊息提示,圓形按鈕等
上面的應用了solid、padding、stroke、gradient、size幾個特性。size是用來設定形狀大小的,如下:
size: 設定形狀預設的大小,可設定寬度和高度
android:width 寬度
android:height 高度
數字0是預設的橢圓,只加了solid填充顏色,
數字1則加了上下左右4dp的padding,
後面的數字都是正圓,是通過設定size的同樣大小的寬高實現的,也可以通過設定控制項的寬高一致大小來實現。
數字3加了描邊,
數字4是鏤空描邊,
數字5是虛線描邊,
數字6用了radial漸層。注意,使用radial漸層時,必須指定漸層的半徑,即android:gradientRadius屬性。
以下是漸層的代碼實現,檔案為bg_oval_with_gradient.xml:
引用的代碼:
line
line主要用於畫分割線,是通過stroke和size特性組合來實現的,先看虛線的代碼:
畫線時,有幾點特性必須要知道的:
只能畫水平線,畫不了豎線;線的高度是通過stroke的android:width屬性設定的; size的android:height屬性定義的是整個形狀地區的高度; size的height必須大於stroke的width,否則,線無法顯示;線在整個形狀地區中是置中顯示的;線左右兩邊會留有空白間距,線越粗,空白越大;引用虛線的view需要添加屬性android:layerType,值設為”software”,否則顯示不了虛線。
引用:
ring
首先,shape根項目有些屬性只適用於ring類型,先過目下這些屬性吧:
android:innerRadius 內環的半徑 android:innerRadiusRatio 浮點型,以環的寬度比率來表示內環的半徑,預設為3,表示內環半徑為環的寬度除以3,該值會被 android:innerRadius覆蓋 android:thickness 環的厚度 android:thicknessRatio 浮點型,以環的寬度比率來表示環的厚度,預設為9,表示環的厚度為環的寬度除以9,該值會被-android:thickness覆蓋 android:useLevel 一般為false,否則可能環形無法顯示,只有作為LevelListDrawable使用時才設為true
第一個圖只添加了solid;
第二個圖只添加了gradient,類型為sweep;
第三個圖只添加了stroke;
第四個圖添加了gradient和stroke兩項特性。
以下為第四個圖的代碼:
如果想讓這個環形旋轉起來,變成可用的進度條,則只要在shape外層包多一個rotate元素就可以了。
引用
android:indeterminateDrawable
Layer
本案例參考剛哥的部落格layer-list
向前輩學習~
效果分析:
TAB的背景效果 + 帶陰影的圓角矩形
在這裡我們沒有用到任何的圖片,完全是依靠 shape+selector+layer-list完成。
使用layer-list可以將多個drawable按照順序層疊在一起顯示,像中的Tab,是由一個紅色的層加一個白色的層疊在一起顯示的結果,陰影的圓角矩形則是由一個灰色的圓角矩形疊加上一個白色的圓角矩形。
Tab背景的代碼:
第一種實現方式:
bg_tab_selector.xml
bg_tab_selected.xml
bg_tab_unselected.xml
第二種實現方式 (只是把第一種的實現方式寫到一個檔案裡)
bg_tab_selected.xml
文本部分:
res/color/text_tab_selector.xml
帶陰影的圓角矩形:
bg_shadow_corners_rectangle.xml
引用:
總結:
從上面的範例程式碼可以看到,layer-list可以作為根節點,也可以作為selector中item的子節點。 layer-list可以添加多個item子節點,每個item子節點對應一個drawable資源,按照item從上到下的順序疊加在一起,再通過設定每個item的位移量就可以看到陰影等效果了 layer-list的item可以通過下面四個屬性設定位移量:
android:top 頂部的位移量
android:bottom 底部的位移量
android:left 左邊的位移量
android:right 右邊的位移量
這四個位移量和控制項的margin設定差不多,都是外間距的效果。如何不設定位移量,前面的圖層就完全擋住了後面的圖層,從而也看不到後面的圖層效果了。比如上面的例子,Tab背景中的白色背景設定了android:bottom之後才能看到一點紅色背景。那麼如果位移量設為負值會怎麼樣呢?經過驗證,位移超出的部分會被截掉而看不到,不信可以自己試一下。有時候這很有用,比如當我想顯示一個半圓的時候。
另外,關於item的用法,也做下總結:
根節點不同時,可設定的屬性是會不同的,比如selector下,可以設定一些狀態屬性,而在layer-list下,可以設定位移量;就算父節點同樣是selector,放在drawable目錄和放在color目錄下可用的屬性也會不同,比如drawable目錄下可用的屬性為android:drawable,在color目錄下可用的屬性為android:color; item的子節點可以為任何類型的drawable類標籤,除了上面例子中的shape、color、layer-list,也可以是selector,還有其他沒講過的bitmap、clip、scale、inset、transition、rotate、animated-rotate、lever-list等等。Selector
之前的博文底部導覽列的幾種實現方式底部是採用了selector樣式,也可以看下。
先看下最後的實現效果:
下面切入正題:
shape雖然可以自訂矩形、圓形、線形和環形,以及有哪些需要注意的地方。不過,shape只能定義單一的形狀,而實際應用中,很多地方比如按鈕、Tab、ListItem等都是不同狀態有不同的展示形狀。舉個例子,一個按鈕的背景,預設時是一個形狀,按下時是一個形狀,不可操作時又是另一個形狀。有時候,不同狀態下改變的不只是背景、圖片等,文字顏色也會相應改變。而要處理這些不同狀態下展示什麼的問題,就要用selector來實現了。
selector標籤,可以添加一個或多個item子標籤,而相應的狀態是在item標籤中定義的。
定義的xml檔案可以作為兩種資源使用:drawable和color。
作為drawable資源使用時,一般和shape一樣放於drawable目錄下,item必須指定android:drawable屬性;
作為color資源使用時,則放於color目錄下,item必須指定android:color屬性。
可設定的狀態:
如果不願意手工編寫,可以在Android Studio使用外掛程式android-selector-chapek,但是圖片的命名規則需要按照規範才可以自動產生。
注意事項:
selector作為drawable資源時,item指定android:drawable屬性,並放於drawable目錄下; selector作為color資源時,item指定android:color屬性,並放於color目錄下; color資源也可以放於drawable目錄,引用時則用@drawable來引用,但不推薦這麼做,drawable資源和color資源最好還是分開;
android:drawable屬性除了引用@drawable資源,也可以引用@color顏色值;但android:color只能引用@color; item是從上往下匹配的,如果匹配到一個item那它就將採用這個item,而不是採用首選的規則;所以設定預設的狀態,一定要寫在最後,如果寫在前面,則後面所有的item都不會起作用了。
另外,selector標籤下有兩個比較有用的屬性要說一下,添加了下面兩個屬性之後,則會在狀態改變時出現淡入淡出效果,但必須在API Level 11及以上才支援:
android:enterFadeDuration 狀態改變時,新狀態展示時的淡入時間,以毫秒為單位
android:exitFadeDuration 狀態改變時,舊狀態消失時的淡出時間,以毫秒為單位
最後,關於ListView的ListItem樣式,有兩種設定方式,一種是在ListView標籤裡設定android:listSelector屬性,另一種是在ListItem的布局layout裡設定android:background。
但是,這兩種設定的結果卻有著不同。同時,使用ListView時也有些其他需要注意的地方,總結如下:
android:listSelector設定的ListItem預設背景是透明的,不管你在selector裡怎麼設定都無法改變它的背景。所以,如果想改ListItem的預設背景,只能通過第二種方式,在ListItem的布局layout裡設定android:background。當觸摸點擊ListItem時,第一種設定方式下,state_pressed、state_focused和state_window_focused設為true時都會觸發,而第二種設定方式下,只有state_pressed會觸發。
當ListItem裡有Button或CheckBox之類的控制項時,會搶佔ListItem本身的焦點,導致ListItem本身的觸摸點擊事件會無效。那麼,要解決此問題,有三種解決方案:
將Button或CheckBox換成TextView或ImageView之類的控制項
設定Button或CheckBox之類的控制項設定focusable屬性為false
設定ListItem的根布局屬性- android:descendantFocusability=”blocksDescendants”
第三種是最方便,也是推薦的方式,它會將ListItem根布局下的所有子控制項都設定為不能擷取焦點。android:descendantFocusability屬性的值有三種,其中,ViewGroup是指設定該屬性的View,本例中就是ListItem的根布局:
beforeDescendants:ViewGroup會優先其子類控制項而擷取到焦點 afterDescendants:ViewGroup只有當其子類控制項不需要擷取焦點時才擷取焦點 blocksDescendants:ViewGroup會覆蓋子類控制項而直接獲得焦點