寫出高效 Layout 佈局文件的小技巧
在 Android 開發中,我們習慣關注的是怎麼寫出易用可讀以及高效能的 Java 程式碼,但是我們忽略了 layout 佈局文件。 Layout 佈局的 Render 速度會影響你的 App 執行速度。這邊介紹幾個小技巧來幫助我們寫出更多高效的 Layout 佈局文件
在一個 TextView 中使用複合的 drawable
我們常常會需要在 TextView 旁邊增加一張圖片,使用 TextView 本身的屬性同時顯示圖片和文字。
有些人首先想到的做法用一個 LinearLayout 或 RelativeLayout 來包含一個 TextView 和 ImageView,最後用到了三個UI元件和一堆 Layout 佈局程式碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/andropic1"/> <TextView android:layout_width="100dp" android:layout_height="40dp" android:text="layout tips" android:textSize="18dp" android:textAlignment="center" android:gravity="center"/> </LinearLayout> </RelativeLayout>
|
用 TextView 的 compound drawable 是一個更好的解決方案。只要需一個屬性就能完成。修改後的佈局文件如下 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:layout_width="120dp" android:layout_height="40dp" android:text="layout tips" android:textSize="18dp" android:textAlignment="center" android:layout_centerInParent="true" android:gravity="center"
android:drawableLeft="@drawable/andropic1" android:drawableStart="@drawable/andropic1" android:drawablePadding="0dp" /> </RelativeLayout>
|
從上面佈局可以發現,變成只有一個 TextVIew 。但是如果要更改 drawable 的圖片size ,這種方式是沒有辦法在 layout 檔做修改的。
幾個主要屬性 :
- drawableLeft - 指定 drawable 放在文字的左邊
- drawableStart - 作用和 drawableLeft 相同,但是它是基於新的 Android 4.2 Api。支援RTL。
- drawablePadding - 指定文字和 drawable 之間 padding 多少
使用 LinearLayout 分隔線
分隔現在 app 非常常見。 LinearLayout 中有一個屬性可以幫你添加分隔線。
首先我們必須先創建一個 divider shape 來當作分隔線。
1 2 3 4 5
| <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <size android:width="1dp"/> <solid android:color="@color/colorPrimaryDark"/> </shape>
|
接著將 shape 加入到 LinearLayout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@android:color/white" android:divider="@drawable/divider_horizontal" android:dividerPadding="5dp" android:showDividers="middle">
<TextView android:layout_width="0dp" android:layout_weight="0.5" android:layout_height="wrap_content" android:gravity="center" android:text="Left" android:textSize="20dp"/>
<TextView android:layout_width="0dp" android:layout_weight="0.5" android:layout_height="wrap_content" android:gravity="center" android:text="Right" android:textSize="20dp"/>
</LinearLayout> </RelativeLayout>
|
主要有三個 xml 屬性
- divider - 用來定義一個 drawable 或者 color 作為分隔線。
- showDividers - 指定分隔線在哪裡顯示,可以顯示在開始位置、中間、結尾或者不顯示。
- dividerPadding - 讓 divider 增加 padding 。
使用 Space 元件
當需要在兩個 UI 元件中添加間距的時時候,你可能會需要 padding or margin。有時候最後的 layout 文件可讀性很差。當你需要修改佈局元件時,你發現這裡有一個10dp 的 paddingTop,另外一邊又有一個 3dp 的 marginBottom,還有一個 8dp 的 paddingBottom在第三個元件上,這時候會很難去修改這樣的佈局元件。有些人會在兩個元件中增加 View 或 LinearLayout 來解決這個問題,看起來很簡單可以解決,但是或多或少會影響 app 的渲染效能,當這類的 View 元件更多時,更可能造成 App 執行緩慢。
這裡有一個更容易的方法就是 Space,Space 繼承 View,但是卻沒有在 canvas 中渲染任何事物。下面為 Space 元件的實現程式碼
1 2 3 4 5 6 7 8
|
@Override public void draw(Canvas canvas) { }
|
使用方法非常簡單,只要在兩個元件中添加一個 Space 即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="我是標題" android:textSize="36dp"/>
<Space android:layout_width="match_parent" android:layout_height="100dp"/>
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="我是內容"/> </LinearLayout>
|
使用 和 標籤
重用佈局元件是一個保持 app 一致的方法,當以後有任何改變時,只需要更改一個元件就可以了。Android 提供了 標籤幫助你可以復用 Layout。
假設我們希望每個頁面都能有一個共用的 ToolBar。首先我們先創建一個共用的toolbar layout :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar" android:fitsSystemWindows="true">
<TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="ToolBar" android:textColor="@color/colorAccent" android:textSize="20dp" android:gravity = "center" android:id="@+id/toolbar_title" />
</android.support.v7.widget.Toolbar>
|
接著在我們原本的 layout 檔中 include 這個 toolbar layout :
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/drawer_layout" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <include android:id="@+id/toolbar" layout="@layout/toolbar"/> </LinearLayout>
|
使用 標籤可以只用一行程式碼在app的每個頁面添加你的toolbar,任何改變都會自動更新到所有頁面。
除了,也常用來從你的 view 層次結構中減少不必要的元件,它會移除沒必要的嵌套的佈局,例如,如果被包含佈局文件的根是一個的LinearLayout ,然後你把它包括包含在另外一個的LinearLayout裡面,2個嵌套的LinearLayouts是沒有必要的,這個嵌套的佈局沒有任何作用除了影響UI性能。在這種情況下可以用來替換被包含佈局的根LinarLayout移除不必要的視圖。
關於和的更多資訊你可以查看官方文檔。