標籤:btn 內容 parent tom appear 常見 strong raw nbsp
源文地址: 巧用Drawable 實現Android UI 元素間距效果
在大部分的移動UI或者Web UI都是基於網格概念而設計的。這種網格一般都是有一些對其的方塊組成。然後它們組合成為一個塊。
使用網格這種設計原則能夠有助於對齊UI元素,提升UI的一致性,同一時候還能讓使用者更加easy的擷取UI上麵包括的內容。
簡而言之。網格是一個相當的強大的設計工具。
開發人員在使用網格設計原則的時候須要在UI 元素之間加入一些額外的間距,比方padding、margin或者spacing(依據你的設計方案來選擇使用哪種間距) 。這些間距有利於在不同的塊之間設定清晰的分隔帶同一時候不會總體UI的可讀性。這些間距對我們Android 開發人員來說也不陌生,我們在設計Android 介面時,也會使用View 的padding 和 margin 來達到類似的效果。在Android 開發中,為了將UI 和商務邏輯分隔,我們會使用 XML來定義UI。這樣的做法對於比較固定的UI非常有效果,但當這些UI元素須要依據商務邏輯來確定隱藏或者顯示的狀態時,這樣的做法就有點困難了。這篇文章就依據這樣的情況提出了一些Android開發技巧來應對動態網格UI。
沒有間距的UI
首先讓我們來看一個簡單的範例。我們建立一個簡單的 LinearLayout 。
然後我們在TextView (顯示“Application logo”)下方再內建一個 LinearLayout 。我們在當中水平依次放置3個Button。
最後得到的例如以所看到的:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="@dimen/spacing_medium"> <TextView android:layout_width="match_parent" android:layout_height="128dp" android:background="@color/light_gray" android:gravity="center" android:text="@string/application_logo" android:textAppearance="@android:style/TextAppearance.Material.Display1" /> <LinearLayout android:id="@+id/buttons_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/btn_first" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/purple" android:text="@string/button_1" /> <Button android:id="@+id/btn_second" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/indigo" android:text="@string/button_2" /> <Button android:id="@+id/btn_third" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/teal" android:text="@string/button_3" /> </LinearLayout></LinearLayout>
加入間距後的UI
的所展示的UI就是基於網格設計的。當時UI裡面的元素之間都沒有間距。為了讓使用者更好地區分這些UI元素。我們給id 為 @id/buttons_container 的 LinearLayout 加入屬性 android:layout_marginTop="@dimen/spacing_medium" ;給id 為 @id/btn_first 和@id/btn_second 的兩個 Button 分別加入屬性 android:layout_marginRight="@dimen/spacing_medium" ;這時的UI效果例如以所看到的:
加入了間距之後。總體的UI效果好多了,可讀性更強了。
可當我們動態隱藏某些 View 的時候就會出現一些問題了。
我們如果第三個Button 會依據使用者的裝置是否安裝了 Google Play Services 來決定它的展示。如果這個裝置沒有 Google Play Services,那我們就把這個 Button to View.GONE 的 visibility 屬性設為 View.GONE, 所得效果例如以:
出來的效果與我們預料中的一樣,第三個 Button 沒有再顯示了,可是第二個 Button 的右邊沒有與上面的TextView 右邊對齊。出現這樣的問題的解決辦法是:擁有 margin 屬性的view 會覺得margin相應方向存在鄰接 view。比如。每一個擁有right/top margin view會覺得它的 right/top 方向有一個鄰接 view,因此,這個相應 margin 也就會生效。就算這個鄰接view已經隱藏了。
設定間距的折衷方案——Java 和 GridLayout
一個比較直接的解決方式就是在Java 代碼裡面手動改變對應的margin 值,但說實話這不是一個好的方案。還有一個方案就是使用可以自己主動處理元素之間的間距的布局。GridLayout 就符合這種要求。可是這個布局讓人蛋疼的是元素之間的間距不能自己定義,僅僅能使用預設的間距。
設定間距的最佳方案——LinearLayout 的divider
實際上 LinearLayout 已經有一個處理這樣的元素之間的間距的屬性了。
這個屬性卻沒怎麼被大家發現。一直非常低調,但它的效果相當奇妙。
所以我們說的第三個方案就是使用一個固定高寬的 Drawable 作為 LinearLayout 的 元素分隔線(divider):
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:width="@dimen/spacing_medium" android:height="@dimen/spacing_medium" /> <solid android:color="@android:color/transparent" /></shape>
如今你就能夠把這個新建立的 Drawable 設為LinearLayout 的 divider。這樣這個Drawable 就能讓元素之間產生間距了:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@drawable/spacer_medium" android:orientation="vertical" android:padding="@dimen/spacing_medium" android:showDividers="middle"> <!-- TextView --> <LinearLayout android:id="@+id/buttons_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@drawable/spacer_medium" android:orientation="horizontal" android:showDividers="middle"> <!-- Buttons --> </LinearLayout></LinearLayout>
總結
Android 架構裡面有很多的特效能夠用來實現一些不常見的方案,並且最後效果出其不意。
定義 Drawable 就是當中一種途徑。
假設你能吃透Android 裡面的 Drawable ,那麼你的代碼也可能大大地精簡。
注意:文章LinearLayout的divider 屬性設定是Android API 11 之後加進去的,這意味著Android API 11之前的裝置要使用這個divider須要LinearLayoutCompat。
本文翻譯自:Grid Spacing on Android 原文Cyril Mottier
巧用Drawable 實現Android UI 元素間距效果