在 Android 的開發過程當中,Drawable 常常會被用到,通常會用 Drawable 爲 View 設置一個顯示的效果。而在 Android 下,也提供了不少 Drawable 的默認實現,它們涉及到的內容很是的多,從屬性到方法,可是平常生活中,會用到的只有那麼些方式。android
本文就在工做中,Drawable 的經常使用方式,整理出一篇文章,會攜帶一些場景,若有缺漏的,能夠在文末留言,本文采用精益編寫,若有必要,會一直長期更新。算法
Drawable 其實是一個抽象類,主要用於將一個可繪製的資源,按要求繪製成圖形,顯示在屏幕之上。c#
Android 爲了讓開發者更方便的使用 Drawable ,提供了不少 Drawable 的實現類,並提供對應的 xml 的屬性配置。設計模式
例如:佈局
同時它也可使用代碼的方式實現,它們的效果是同樣的。學習
實際上,不論是使用 xml 資源的方式,仍是直接在邏輯中硬編碼的方式,它們最終顯示的效果都是同樣的,以下圖,一個藍色的方塊:動畫
Android 中,爲咱們提供了很是多默認的 Drawable,正常來講,通常是足夠咱們使用的,它們的關係以下圖:編碼
基本上,從 XxxDrawable 這種類名,就能夠看出來它對應的 Xml 資源的命名,惟一須要注意的是 的實現類是 GradientDrawable ,而不是 ShapeDrawable。設計
有些 App 中,按鈕的圓角,若是背景只是一個純色或者是簡單的規則漸變,是可使用 來完成的,如前面示例同樣。3d
若是想要爲其增長一個圓角,能夠在 中使用 corners
屬性,它支持設置一個 android:radius
,用來設置四個角落的圓角角度,固然也提供了單獨的屬性去設置某個角的圓角角度,例如,android:topLeftRadius
就是設置左上的圓角的。
實現的效果以下:
想在圓角的 上,加一個邊框,可使用 stroke
屬性,固然,不是設置 corners
屬性,它就不是一個圓角的效果了。
stroke 用於設置邊框,能夠指定顏色和邊框的寬度。
能夠看到這裏指定了一個黃色的邊框,效果以下圖:
在 中,若是使用 stroke
來設置邊框,它會在四周都加上邊框,可是有時候,咱們只須要在底部或者單邊繪製一個邊框的效果,例如:一個列表頁裏每一項的分割線。
這個時候,就可使用 ,使用兩個 shape 來疊加實現。
這樣的一個 Drawable,若是做爲背景的話,顯示效果就是在白色背景下,有一條 1px 的灰線。固然其餘方向能夠參考這個方案,截圖發現 1px 的線不太明顯,這裏就不放圖了。
除了支持一個純色規則圖案,它還能夠實現漸變的效果,用的最多的,就是線性漸變。
例如一些視頻 App 的 UI 設計,會將視頻名稱直接佈局在視頻海報上,就可使用線性漸變的 來實現簡單的背景效果,使其在白色的視頻海報上,顯示的效果依然能看得清楚文字。
例如通常的視頻App :
看到其實海報下面的文字,底部是有一個漸變的背景色的。
這種漸變的效果,可使用 gradient
標籤來設置。
gradient
支持的屬性,基本上看名稱就能夠知道意思,惟一須要注意的是 android:angle
這個屬性,用於設定漸變的角度,可是它不是任何值都支持的,只支持 45 的倍數。
效果以下圖:
一般在圖片加載的過程當中,會爲其定義一個默認圖片。通常的設計都是會將這個默認圖作的很是的簡潔,例如中間一個 App 主題的 Icon,而後其它地方純色鋪平。
相似下面這種效果:
這種默認的圖片,固然你可使用一張等大的圖,可是這樣不利於適配,不一樣的 UI 設計尺寸,你須要提供不一樣的圖片。固然你也可使用 9patch 的圖片,可是你會發現有些 density 爲 2.75 這種奇葩的手機下,圖標會微微偏移,不在正中間。因此這裏可使用一個 的 Drawable 來實現。
是一個帶層級效果的 Drawable ,有點相似於佈局中的 FrameLayout 的效果。它支持設置多個 Drawable ,並將它們疊加在一塊兒。
因此這樣的場景下,咱們就須要一個純色的背景加一張小圖,便可實現默認圖的效果。
下面是 xml 的實現代碼:
下面是運行後的效果圖:
對一個按鈕,設計一個按下的效果。可使用 這個 Drawable。它支持在不一樣的狀態下,顯示不一樣的 Drawable。
一樣也支持設置多個 Drawable ,區別在於你須要額外的爲每一個 Drawable 設置不一樣的狀態,若是不設置,則爲默認顯示的狀態。
這些不一樣的狀態,在 xml 裏,都是以 android:state_Xxx 開頭來定義的,將其設置爲 true 便可生效。
Android 爲咱們提供了很是多的狀態,比較經常使用的有:
接下來讓咱們看一個實際的按鈕例子,這裏只爲其設置按下的效果,xml 代碼以下:
實現效果以下:
這個沒啥好說的,結合上面的效果就能夠作到。你能夠選擇將它們寫在不一樣的 Drawable 中,也能夠在一個 xml 文件中,使用不一樣 item 來完成。Item 標籤是能夠支持內部再嵌套一個 Drawable 的。
按下效果除了使用 作一個變色的效果以外,在 Api Level 21 以後,能夠嘗試使用 StateListAnimator 來實現一個 Material Design 的按下效果。
具體細節能夠看看我以前的一篇文章:《利用 StateListAnimator 爲你的點擊加個動畫吧!》
StateListAnimtor 使用起來很是的簡單:
setStateListAnimator()
方法或者 android:stateListAnimator
屬性,設置到 View 上。舉個例子。
首先在 /res/animtor 目錄下,建立一個 btn_press_animator.xml
文件。
能夠看到,和 StateListDrawable 同樣,它也是經過 android:state_xxx
屬性來定義不一樣的 Animator 的,若是存在多個 Animator ,可使用 標籤將其包裹起來。 這裏只是簡單的在 state_pressed 的時候,作了一個縮小的動畫。
而後,定義一個 View,爲其設置屬性 android:stateListAnimator="@animator/btn_press_animator"
。
來看看運行的效果:
假若有相似氣泡提示的效果,以下圖。
這樣的效果,除了使用 9patch 來實現以外,還能夠拿兩個 Drawable 來拼接實現,這就須要一個圓角的矩形和一個三角的 Drawable。
三角 Drawable 的實現思路很清奇,是使用一個矩形的 shape ,經過使用 rotate 實現的旋轉,來達到尖角的效果。
這個例子,就是上圖的實現效果,是一個黃色的倒三角。若是想要的是一個正三角,只須要改變旋轉的角度就能夠了。
在 Drawable 中,若是使用的是 BitmapDrawable 或者 NinePatchDrawable(9patch) 的資源的話,可使用 android:tint 屬性爲其着色。
默認狀況下,待着色的圖片資源,會將其全部有顏色地方,都着色成咱們指定的顏色,可是會保留透明度。
效果圖以下,上面是原圖,下面是使用 tint 以後的效果:
前面這裏給的是 tint 默認的效果,還能夠經過 android:tintMode 指定成不一樣的着色效果,例以下面將 android:tintMode 指定成 screen 以後,效果就徹底不同了。
有時候,做爲一些有規則的圖片的背景,可使用一張很小的圖片,而後設定 android:tileMode 屬性,爲其設定一個平鋪的效果。
tileMode 能夠指定多個屬性值,用於指定不一樣的效果,如下就是兩個比較經常使用的,上圖使用的是 repeat ,下圖使用的是 mirror。
若是想要一個 ImageView 上,根據不一樣的條件顯示不一樣的 Drawable ,可使用 。從名字上就能夠看出它是一個帶層級的 Drawable 組合,和 很像,可是區別在於它的顯示狀態是咱們邏輯可控的。最多見的例子是拿它實現一個開關的燈泡,兩態的圖片,一個表示開燈,一個表示關燈,相信你們應該都見過例子。
今天舉一個例子,給某個圖標加紅點的邏輯。固然咱們也可使用經過一個 FrameLayout 來實現,可是今天咱們試試用 來實現它。
這裏使用一個 ,內部根據不一樣的 maxLevel 和 minLevel 來控制範圍,這裏只有兩態,因此直接讓它們取值一致。紅點使用 作了一個層疊,在右上角上,直接畫了一個大小爲 5dp 的紅色圓點。
最終咱們能夠經過 ImageView 的 setImageLevel()
方法來控制顯示的內容。
到這裏基本上涵蓋了 Drawable 大部分的使用場景,在實際例子中學東西是印象最深入的。固然,Drawable 的使用不止這些,還有一些例如拿 ClipDrawable 來實現一個切割進度的效果之類的,這種還須要寫邏輯代碼,就不在本文的範圍內了,本文主要介紹一些靜態能實現的效果。
你只須要掌握最基本的規則,什麼 Drawable 能實現什麼效果,具體碰到實際需求的時候,再來細緻的研究,基本上微調一下就可使用。
若是你還又什麼更有意思的 Drawable 使用技巧,歡迎在文末留言,咱們一塊兒討論一下,若有須要,會持續更新。
今天在承香墨影公衆號的後臺,回覆『成長』。我會送你一些我整理的學習資料,包含:Android反編譯、算法、設計模式、虛擬機、Linux、Kotlin、Python、爬蟲、Web項目源碼。
推薦閱讀: