一切以官方文檔為主
官方文檔https://developer.android.com/guide/topics/resources/drawable-resource?hl=zh-cn#Shape
什么是可繪制形狀
可以理解為用xml文件來描述一個簡單的Drawable圖形,比如說以下這段xml就可以用來描述一個白色的圓形:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><solid android:color="@color/white" />
</shape>
標準語法一覽
<?xml version="1.0" encoding="utf-8"?>
<shapexmlns:android="http://schemas.android.com/apk/res/android"android:shape=["rectangle" | "oval" | "line" | "ring"] ><cornersandroid:radius="integer"android:topLeftRadius="integer"android:topRightRadius="integer"android:bottomLeftRadius="integer"android:bottomRightRadius="integer" /><gradientandroid:angle="integer"android:centerX="float"android:centerY="float"android:centerColor="integer"android:endColor="color"android:gradientRadius="integer"android:startColor="color"android:type=["linear" | "radial" | "sweep"]android:useLevel=["true" | "false"] /><paddingandroid:left="integer"android:top="integer"android:right="integer"android:bottom="integer" /><sizeandroid:width="integer"android:height="integer" /><solidandroid:color="color" /><strokeandroid:width="integer"android:color="color"android:dashWidth="integer"android:dashGap="integer" />
</shape>
控制形狀
其中 Shape 根標簽下的 shape 屬性決定了這個Drawable的形狀 , 如圖所示一共有四種可選值 ,分別是:
-
Rectangle 矩形
-
Oval 橢圓/圓形
-
Line 線
-
Ring 圓環
不同的形狀下有不同的特定標簽來決定其效果。
通用屬性
除了特定的標簽屬性之外,還有一些通用的標簽屬性來決定一些通用的效果。
Size
最基礎的屬性,用來確定圖形所處的矩形范圍大小,具體就兩個子屬性:
<size>android:height尺寸。形狀的高度,采用尺寸值或尺寸資源的形式。android:width尺寸。形狀的寬度,采用尺寸值或尺寸資源的形式。
Padding
顧名思義,Padding屬性是來確定圖形填充的內邊界的,具體如下:
<padding>android:left尺寸。左側內邊距,采用尺寸值或尺寸資源的形式。android:top尺寸。頂部內邊距,采用尺寸值或尺寸資源的形式。android:right尺寸。右側內邊距,采用尺寸值或尺寸資源的形式。android:bottom尺寸。底部內邊距,采用尺寸值或尺寸資源的形式。
Solid & Stroke
這兩個屬性放在一起說,前者是用來確定填充圖形的顏色,后者用來確定描述圖形輪廓線的屬性,比如說同一個xml文件,若我們定義了Solid,其效果為下:
若我們定義了Stroke,效果則為:
可以看到,差別即為一個填充圖形,一個對圖形描邊。
不過,我們也可以既對其描邊又對其填充:
兩個標簽的描述詳細如下:
<solid>android:color顏色。應用于形狀的顏色,采用十六進制值或顏色資源的形式。<stroke>android:width尺寸。線的寬度,采用尺寸值或尺寸資源的形式。android:color顏色。線的顏色,采用十六進制值或顏色資源的形式。android:dashGap尺寸。短劃線的間距,采用尺寸值或尺寸資源的形式。僅在已設置 android:dashWidth 的情況下有效。android:dashWidth尺寸。每個短劃線的長度,采用尺寸值或尺寸資源的形式。僅在已設置 android:dashGap 的情況下有效。
至于stroke屬性的dash,我們可以測試一下效果:
可以看到實際上就是一個虛線的效果。
Gradient
漸變標簽,簡而言之就是我們可以設置圖形的填充顏色,其實這個就是相當于為圖形的solid標簽設置了一個漸變顏色,該如何理解呢?之前我們在Solid&Stroke標簽中提到過,我們可以既對其描邊,又對其填充,這里我們也同時設置stroke標簽和gradient標簽,效果如下:
具體標簽如下:
<gradient>android:angle整數。漸變的角度(以度為單位)。0 為從左到右,90 為從下到上。該屬性值必須是 45 的倍數。默認值為 0。android:centerX浮點數。漸變中心的相對 X 軸位置 (0 - 1.0)。android:centerY浮點數。漸變中心的相對 Y 軸位置 (0 - 1.0)。android:centerColor顏色。起始顏色與結束顏色之間的可選顏色,采用十六進制值或顏色資源的形式。android:endColor顏色。結束顏色,采用十六進制值或顏色資源的形式。android:gradientRadius浮點數。漸變的半徑。僅當 android:type="radial" 時適用。android:startColor顏色。起始顏色,采用十六進制值或顏色資源的形式。android:type關鍵字。要應用的漸變圖案的類型。android:useLevel布爾值。如果此屬性用作 LevelListDrawable,該值為 true。
這個標簽相比之前的標簽來說復雜一點,我們來簡要說明一下,以我的理解,如有錯誤還請指出。首先說明一下type屬性,該屬性決定了顏色漸變的方式:
這個類似于自定義View中的著色器的漸變模式,我們借用朱凱老師的自定義View中的效果圖:
-
線性漸變:
-
-
徑向漸變:
-
-
扇形漸變:
-
其中startColor,endColor, centerColor,三個屬性確定的是漸變起始位置,結束位置,和中間位置的顏色,這三個屬性也是漸變中都有效的屬性。
對于線性漸變來說,其特定的屬性是angle,其確定的是顏色漸變的方向,這樣說可能比較抽象。比如說默認情況下,angle屬性為0,即漸變方向為0度角方向(X軸正向):
當我們設置angle屬性為45度時,效果就如下:
總結一下,我們可以以圖形左下角為坐標原點,以angle屬性的角度方向引出一條射線(即極坐標系下),射線起點的顏色為startColor,延射出的方向向endColor漸變。
特有屬性
Corners
該標簽是專門為矩形,即shape為rectangle時設計的,它的效果也很簡單,就是為矩形圖形設置圓角,我們可以直觀地感受一下,比如當我們設置了以下一段xml時:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><cornersandroid:topLeftRadius="2dp"android:topRightRadius="4dp"android:bottomLeftRadius="6dp"android:bottomRightRadius="8dp"/><sizeandroid:width="50dp"android:height="50dp"/><gradientandroid:angle="45"android:startColor="@color/white"android:endColor="#FE2C55"android:gradientRadius="20dp"/>
</shape>
最終呈現出來的效果如下:
可以看到四個圓角都按照我們的corners標簽里設置的值來顯示。
corners標簽具體有五個可選的屬性:
<corners>為形狀創建圓角。僅當形狀為矩形時適用。android:radius尺寸。所有角的半徑,采用尺寸值或尺寸資源的形式。每個角的此屬性都會被以下屬性替換。android:topLeftRadius尺寸。左上角的半徑,采用尺寸值或尺寸資源的形式。android:topRightRadius尺寸。右上角的半徑,采用尺寸值或尺寸資源的形式。android:bottomLeftRadius尺寸。左下角的半徑,采用尺寸值或尺寸資源的形式。android:bottomRightRadius尺寸。右下角的半徑,采用尺寸值或尺寸資源的形式。
下邊的四個屬性我們都用過了,第一個屬性是為所有的四個圓角設置統一的一個值,不過當下邊的四個屬性被設置的時候,會優先展示下邊的四個屬性,也就是說第一個屬性會失效。
Ring下的標簽
這個標簽比較迷,首先來根據官網上的文檔給出解釋:
根據這個描述,理論上來說其效果應該是描述一個類似于圓環的東西,但是實際效果卻是這樣:
顯示的是一個類似于菱形的東西,實機效果也是如此,所以說還是不建議用這種方法來展示環狀,我們可以用stroke屬性來實現環,比如:
其他屬性
除了文檔中介紹的幾種屬性之外,我們在shape根標簽下還可以設置其他的幾種屬性:
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"android:dither="true" //是否開啟圖像抖動android:tintMode="multiply" //著色模式android:tint="@color/white" //著色器android:visible="true" //是否可見android:opticalInsetLeft="@dimen/cardview_compat_inset_shadow" //光學插值 - 不太懂android:opticalInsetBottom="@dimen/cardview_compat_inset_shadow"android:opticalInsetRight="@dimen/cardview_compat_inset_shadow"android:opticalInsetTop="@dimen/cardview_compat_inset_shadow">
這里簡單介紹一下圖像抖動:
指把圖像從較高色彩深度(即可用的顏色數)向較低色彩深度的區域繪制時,在圖像中有意地插入噪點,通過有規律地擾亂圖像來讓圖像對于肉眼更加真實的做法。在實際的應用場景中,抖動更多的作用是在圖像降低色彩深度繪制時,避免出現大片的色帶與色塊。