今天咱們來探究一下android的樣式。 其實,幾乎全部的控件均可以使用 background屬性去引用自定義的XML樣式,因此研究樣式顯得特別重要。 先來看一段樣式代碼:php
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:innerRadiusRatio="10" android:shape="ring" android:thicknessRatio="9" android:useLevel="false">
<stroke android:width="1dp" android:color="@android:color/black" />
</shape>
</item>
</selector>
複製代碼
說一下一些基本的知識:(我也是剛剛纔知道的)android
<?xml version="1.0" encoding="utf-8"?>
bash
xmlns:android="http://schemas.android.com/apk/res/android"
工具
android:visiable
佈局
android:autoMirrored
動畫
android:constantSize
ui
android:dither
編碼
android:enterFadeDuration
spa
android:exitFadeDuration
3d
android:variablePadding
selector標籤下只有item標籤。item的標籤內屬性以下:都是設置控件在什麼狀態下的樣式:
android:drawable 須要入別的xml,默認是背景圖片
android:state_above_achor ?
android:state_accelerated 硬件加速true時的效果
android:state_activated true被激活時的效果,false未激活時的效果
android:state_active true激活後的效果
android:state_checkable true,當CheckBox能使用時顯示該圖片
android:state_checked true,當CheckBox選中時顯示該圖片
android:state_drag_can_accept true 可以 drag 拖拽時圖片
android:state_drag_hovered true 可以 drag 鼠標指針移動到該位置圖片
android:state_empty ?
android:state_enabled true,當該組件能使用時顯示該圖片
android:state_expanded ?
android:state_first ?
android:state_focused true非觸摸模式下得到焦點時顯示圖片
android:state_hovered 鼠標移動到該位置時的樣式
android:state_last ?
android:state_long_pressable 長按的樣式
android:state_middle ?
android:state_multiline ?
android:state_pressed 按下的樣式
android:state_selected 選擇時的樣式
android:state_single true 只有一個元素顯示圖片
android:state_window_focused 當此activity得到焦點在最前面時顯示該圖片
標籤內屬性:
solid: 設置形狀填充的顏色,只有android:color一個屬性
padding: 設置內容與形狀邊界的內間距,可分別設置左右上下的距離
gradient: 設置形狀的漸變顏色,能夠是線性漸變、輻射漸變、掃描性漸變
corners: 設置圓角,只適用於rectangle類型,可分別設置四個角不一樣半徑的圓角,當設置的圓角半徑很大時,好比200dp,就可變成弧形邊了
stroke: 設置描邊,可描成實線或虛線。
size:設置組件大小
矩形:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#0ee"/>
<corners android:radius="20dp"/>
<size android:width="100dp" android:height="100dp"/>
<stroke android:width="2dp" android:color="#000"/>
</shape>
複製代碼
圓形:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#0ee"/>
<corners android:radius="50dp"/>
<size android:width="100dp" android:height="100dp"/>
<stroke android:width="2dp" android:color="#000"/>
</shape>
複製代碼
主要是經過設置padding和size去實現圓的大小,扁正。
橢圓:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="#0ee"/>
<size android:width="200dp" android:height="100dp"/>
<stroke android:width="2dp" android:color="#000"/>
<gradient android:type="linear" android:startColor="#fff" android:endColor="#000"/>
</shape>
複製代碼
注意,使用radial漸變時,必須指定漸變的半徑,即android:gradientRadius屬性。
畫線時,有幾點特性必需要知道的:
實線:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
<size android:width="200dp" android:height="100dp"/>
<stroke android:width="3dp" android:color="#000" />
</shape>
複製代碼
虛線:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
<size android:width="200dp" android:height="100dp"/>
<stroke android:width="3dp" android:color="#000" android:dashWidth="6dp" android:dashGap="2dp"/>
</shape>
複製代碼
首先,shape根元素有些屬性只適用於ring類型,先過目下這些屬性吧:
普通的環形:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring" android:innerRadius="50dp" android:useLevel="false"
android:thickness="5dp">
<solid android:color="#21e1f2"/>
</shape>
複製代碼
layer-list通過一系列的item標籤,從上到下的順序,從低到上把item的效果疊加起來。layer-list能夠做爲根節點,也能夠做爲selector中item的子節點。layer-list能夠添加多個item子節點,每一個item子節點對應一個drawable資源,按照item從上到下的順序疊加在一塊兒,再經過設置每一個item的偏移量就能夠看到陰影等效果了。layer-list的item能夠經過下面四個屬性設置偏移量:
這四個偏移量和控件的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等等。
for example,如下是一個白色背景,有灰色陰影的矩形框。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<layer-list>
<!-- 灰色陰影 -->
<item android:left="1dp" android:top="2dp">
<shape>
<size android:width="20dp" android:height="10dp"/>
<solid android:color="@android:color/darker_gray" />
<corners android:radius="10dp" />
</shape>
</item>
<!-- 白色前景 -->
<item android:bottom="2dp" android:right="1dp">
<shape>
<solid android:color="#FFFFFF" />
<corners android:radius="10dp" />
</shape>
</item>
</layer-list>
</item>
</selector>
複製代碼
主要能夠經過bitmap標籤對圖片作一些設置,如平鋪、拉伸或保持圖片原始大小,也能夠指定對齊方式。
android:src 必填項,指定圖片資源,只能是圖片,不能是xml定義的drawable資源
android:gravity 設置圖片的對齊方式,好比在layer-list中,默認會盡可能填滿整個視圖,致使圖片可能會被拉伸,爲了不被拉伸,就能夠設置對齊方式,可取值爲下面的值,多個取值能夠用 | 分隔:
android:antialias 設置是否開啓抗鋸齒
android:dither 設置是否抖動,圖片與屏幕的像素配置不一樣時會用到,好比圖片是ARGB 8888的,而屏幕是RGB565
android:filter 設置是否容許對圖片進行濾波,對圖片進行收縮或者延展使用濾波能夠得到平滑的外觀效果
android:tint 給圖片着色,好比圖片原本是黑色的,着色後能夠變成白色
android:tileMode 設置圖片平鋪的方式,取值爲下面四種之一: --disable 不作任何平鋪,默認設置 --repeat 圖片重複鋪滿 --mirror 使用交替鏡像的方式重複圖片的繪製 --clamp 複製圖片邊緣的顏色來填充容器剩下的空白部分,好比引入的圖片若是是白色的邊緣,那麼圖片所在的容器裏除了圖片,剩下的空間都會被填充成白色
android:alpha 設置圖片的透明度,取值範圍爲0.0~1.0之間,0.0爲全透明,1.0爲全不透明,API Level最低要求是11,即Android 3.0
android:mipMap 設置是否可使用mipmap,但API Level最低要求是17,即Android 4.2
android:autoMirrored 設置圖片是否須要鏡像反轉,當佈局方向是RTL,即從右到左佈局時纔有用,API Level 19(Android 4.4)才添加的屬性
android:tileModeX 和tileMode同樣設置圖片的平鋪方式,只是這個屬性只設置水平方向的平鋪方式,這是API Level 21(Android 5.0)才添加的屬性
android:tileModeY 和tileMode同樣設置圖片的平鋪方式,只是這個屬性只設置垂直方向的平鋪方式,這是API Level 21(Android 5.0)才添加的屬性
android:tintMode 着色模式,也是API Level 21(Android 5.0)才添加的屬性
點九圖片文件擴展名爲:.9.png,經過點九圖片能夠作局部拉伸,好比,一張圓角矩形圖片,咱們不想讓它的四個邊角都被拉伸從而致使模糊失真,使用點九圖就能夠控制拉伸區域,讓四個邊角保持完美顯示。畫點九圖通常用Android SDK工具集裏的draw9patch工具,只須要在四條邊畫黑線就能夠了,使用nine-patch標籤能夠對點九圖片作一些設置處理,不過可設置的屬性並很少:
color標籤是drawable裏最簡單的標籤了,只有一個屬性:android:color,指定顏色值。這個標籤通常不多用,由於基本均可以經過其餘更方便的方式定義顏色。另外,顏色值通常都在colors.xml文件中定義,其根節點爲resources。
使用inset標籤能夠對drawable設置邊距,其用法和View的padding相似,只不過padding是設置內容與邊界的距離,而inset則能夠設置背景drawable與View邊界的距離。inset標籤的可設置屬性以下:
使用clip標籤能夠對drawable進行裁剪,在作進度條時頗有用。經過設置level值控制裁剪多少,level取值範圍爲0~10000,默認爲0,表示徹底裁剪,圖片將不可見;10000則徹底不裁剪,可見完整圖片。看看clip標籤能夠設置的屬性:
android:drawable 指定drawable資源,若是不設置該屬性,也能夠定義drawable類型的子標籤
android:clipOrientation 設置裁剪的方向,取值爲如下兩個值之一:
android:gravity 設置裁剪的位置,可取值以下,多個取值用 | 分隔:
level的設置須要在代碼中動態去設置,假若有這樣的圖片:
1 . 定義clip.xml:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android" android:clipOrientation="horizontal" android:drawable="@drawable/img4clip" android:gravity="left" />
複製代碼
2 . 在ImageView中引用:
<ImageView android:id="@+id/img" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_img" android:src="@drawable/clip" />
複製代碼
3 . 在代碼中設置level:
ImageView img = (ImageView) findViewById(R.id.img);
img.getDrawable().setLevel(5000); //level範圍值0~10000
複製代碼
效果以下:
clip裏面設置的android:gravity="left"
能夠理解爲,從右邊開始裁剪,由於,裁剪的範圍值是,0-10000,這裏設置成了5000,也就是裁剪一半,效果如上圖。
當須要在一個View中顯示不一樣圖片的時候,好比手機剩餘電量不一樣時顯示的圖片不一樣,level-list就能夠派上用場了。level-list能夠管理一組drawable,每一個drawable設置一組level範圍,最終會根據level值選取對應的drawable繪製出來。level-list經過添加item子標籤來添加相應的drawable,其下的item只有三個屬性:
如下是示例代碼:
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/battery_low" android:maxLevel="10" android:minLevel="0" />
<item android:drawable="@drawable/battery_below_half" android:maxLevel="50" android:minLevel="10" />
<item android:drawable="@drawable/battery_over_half" android:maxLevel="99" android:minLevel="50" />
<item android:drawable="@drawable/battery_full" android:maxLevel="100" android:minLevel="100" />
</level-list>
複製代碼
那麼,當電量剩下10%時則能夠設置level值爲10,將會匹配第一張圖片:
img.getDrawable().setLevel(10);
item的匹配規則是從上到下的,當設置的level值與前面的item的level範圍匹配,則採用。通常item的添加按maxLevel從小到大排序下來,此時minLevel能夠不用指定也能匹配到。如上面代碼就能夠簡化以下:
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/battery_low" android:maxLevel="10" />
<item android:drawable="@drawable/battery_below_half" android:maxLevel="50" />
<item android:drawable="@drawable/battery_over_half" android:maxLevel="99" />
<item android:drawable="@drawable/battery_full" android:maxLevel="100" />
</level-list>
複製代碼
但不能反過來將 android:maxLevel="100" 的item放在最前面,那樣全部電量都只匹配第一條了。
transition實際上是繼承自layer-list的,只是,transition只能管理兩層drawable,另外提供了兩層drawable之間切換的方法,切換時還會有淡入淡出的動畫效果。示例代碼以下:
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/on" />
<item android:drawable="@drawable/off" />
</transition>
複製代碼
transition標籤生成的Drawable對應的類爲TransitionDrawable,要切換時,須要主動調用TransitionDrawable的startTransition()方法,參數爲動畫的毫秒數,也能夠調用reverseTransition()方法逆向切換。
((TransitionDrawable)drawable).startTransition(500);
//正向切換,即從第一個drawable切換到第二個 ((TransitionDrawable)drawable).reverseTransition(500);
//逆向切換,即從第二個drawable切換回第一個
使用rotate標籤能夠對一個drawable進行旋轉操做,在shape篇講環形時最後舉了個進度條時就用到了rotate標籤。另外,好比你有一張箭頭向上的圖片,但你還須要一個箭頭向下的圖片,這時就可使用rotate將向上的箭頭旋轉變成一張箭頭向下的drawable。 先看看rotate標籤的一些屬性吧:
示例代碼以下,目標是將一張箭頭向上的圖片轉180度,轉成一張箭頭向下的圖片:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_arrow" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />
複製代碼
將它引用到ImageView裏,發現圖片根本沒有轉變。其實,要讓它能夠旋轉,還須要設置level值。level取值範圍爲0~10000,應用到rotate,則與fromDegrees~toDegrees相對應,如上面例子的角度範圍爲0~180,那麼,level取值0時,則旋轉爲0度;level爲10000時,則旋轉180度;level爲5000時,則旋轉90度。由於level默認值爲0,因此圖片沒有轉變。那麼,咱們想轉180度,其實能夠將fromDegrees設爲180,而不設置toDegrees,這樣,不用再在代碼裏設置level圖片就能夠旋轉180了。
經過animation-list能夠將一系列drawable構建成幀動畫,就是將一個個drawable,一幀一幀的播放。經過添加item子標籤設置每一幀使用的drawable資源,以及每一幀持續的時間,可設置的屬性以下:
示例代碼以下:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/anim1" android:duration="1000" />
<item android:drawable="@mipmap/anim2" android:duration="1000" />
<item android:drawable="@mipmap/anim3" android:duration="1000" />
</animation-list>
複製代碼
注意:
private ImageButton hh;
hh = (ImageButton) findViewById(R.id.imageButton);
Drawable drawable = hh.getDrawable();
if (!((AnimationDrawable) drawable).isRunning()) {
((AnimationDrawable) drawable).start();
}
複製代碼
rotate標籤只是將原有的drawable轉個角度變成另外一個drawable,它是靜態的。而animated-rotate則會讓drawable不停地作旋轉動畫。animated-rotate可設置的屬性只有四個:
android:drawable 指定drawable資源,若是不設置該屬性,也能夠定義drawable類型的子標籤
android:pivotX 旋轉中心的X座標
android:pivotY 旋轉中心的Y座標
旋轉中心的座標,浮點數或是百分比。 浮點數表示相對於drawable的左邊緣距離單位爲px,如5; 百分比表示相對於drawable的左邊緣距離按百分比計算, 如5%; 另外一種百分比表示相對於父容器的左邊緣,如5%p; 通常設置爲50%表示在drawable中心
android:visible 設置初始的可見性狀態,默認爲false
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/img_daisy" android:pivotX="50%" android:pivotY="50%" android:visible="false" />
複製代碼
注意:
private ImageButton hh;
hh = (ImageButton) findViewById(R.id.imageButton);
Drawable drawable = hh.getDrawable();
if (!((Animatable) drawable).isRunning()) {
((Animatable) drawable).start();
}
複製代碼