Android寫出高效清晰Layout布局文件的一些技巧
人們談論Android性能的時候總是習慣討論怎么寫出清晰高效的Java代碼,卻忽略了layout布局文件。layout布局緩慢的渲染速度對app性能也有的很大的影響。充滿不必要的views和可讀性差的layout文件會讓你的app運行緩慢。在本文中我會分享5個技巧來幫你寫出高效清晰的layout布局文件。(ps:下面的技巧都非常實用,開發過程中很常見,感動哭!)
1. Use compound drawable on a TextView
用TextView本身的屬性同時顯示圖片和文字
(ps:難以理解現在還有很多人不懂得用這個,實實在在的減少很多view啊,哎!)
通常你需要在文本旁邊添加一張圖片,假設你需要添加圖片在文字的左邊,像下面這樣:
不少人首先想到的就是用一個LinearLayout或RelativeLayou來包含一個TextView和ImageView,最后你用了三個UI元素和一大坨代碼。用TextView的compound drawable是一個更好更清晰的解決方案。你只需要一個屬性就可以搞定。
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/batman"
android:drawableLeft="@drawable/batman"
android:drawableStart="@drawable/batman"
android:drawablePadding="5dp">
</TextView>
用到的主要屬性:
drawableLeft- 指定drawable放在文本的左邊
drawableStart- 作用和drawableLeft相同但是它基于新的API(android 4.2)支持RTL
drawablePadding- 指定文本和drawable之間padding
2. ImageView has src and background attribute
同時使用ImageView的src和background屬性實現點擊效果
你應該同時使用它們,在很多情況下你會想要給ImageView添加點擊效果,然后我看到很多人用LinearLayout來包裹一個ImageView來實現。添加另一個view是沒必要的。下面的代碼可以讓你做的更好:
<ImageView
android:id="@+id/image"
android:layout_width="@dimen/batman_logo_width"
android:layout_height="@dimen/batman_logo_height"
android:background="?attr/selectableItemBackground"http://點擊效果
android:src="@drawable/batman_logo_transparent"http://圖片
style="@style/logo_image_style"/>
顯示圖片用”src”屬性,drawable selector 圖片點擊效果用”background”屬性實現,上面用的是android默認提供的selector,當然你也可以換成你自己實現的。下面是最后的效果:(ps:哈哈,效果自己copy上面幾行代碼就可以看到了,實在需要看請KX上網查看原文)。
3. Use LinearLayout divider
用LinearLayout自帶的分割線
分割線在app經常會用到的,使用頻率高到讓你驚訝。但是LinearLayout有一個屬性可以幫你添加分割線。下面的例子中,LinearLayout包含2個TextView和基于他們中間的分割線。
1.Create divider shape(創建shape)
下面是一個簡單的shape divider_horizontal.xml用來當做分割線。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="@dimen/divider_width"/>
<solid android:color="@color/colorPrimaryDark"/>
</shape>
2.Add shape to LinearLayout
<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" //設置padding
android:showDividers="middle">//居中顯示
<TextView android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="wrap_content"
android:gravity="center"
style="@style/Text.Title"
android:text="@string/batman_name"/>
<TextView android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
style="@style/Text.Title"
android:text="@string/superman_name"/>
</LinearLayout>
上面用到了三個xml屬性:
divider -用來定義一個drawable或者color作為分割線
showDividers -指定分割線在哪里顯示,它們可以顯示在開始位置,中間,末尾或者選擇不顯示
dividerPadding -給divider添加padding
4.Use the Space view
使用Space控件
當你需要在2個UI控件添加間距的時候,你可能會添加padding或margin。有時最終的layout文件是非常混亂,可讀性非常差。當你需要解決問題時,你突然意識到這里有一個5dp的paddingTop,那里有一個2dp的marginBottom,還有一個4dp的paddingBottom在第三個控件上然后你很難弄明白到底是哪個控件導致的問題。還有我發現有些人在2個控件之間添加LinearLayout或View來解決這個問題,看起來是一個很簡單解決方案但是對App的性能有很大的影響。
這里有一個更簡單更容易的方法那就是Space,看下官方的文檔:“Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts.” 他們沒有說謊,確實很輕量。如果你看過Space的實現會發現Space繼承View但是沒有繪制任何東西在canvas。
/**
* Draw nothing.
*
* @param canvas an unused parameter.
*/
@Override
public void draw(Canvas canvas) {
}
使用方法很簡單,看下面的圖片,我們想要在在標題和描述之間添加間距。
你只需要簡單的在2個TextView之間添加一個Space就可以了
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Text.Title"
<Space android:layout_width="match_parent"
android:layout_height="10dp"/>//添加間距
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gotham_city_description"
style="@style/Text.Details"/>
5. Use include and merge
使用<include/>和<merge/>標簽(csdn的markdown不知道怎么顯示< /> 坑!所以下面都用include和merge替代,也可以去簡書看)
重用布局是一個保持app一致的好方法,這樣以后有改變的話只要改一個文件就可以了,Android提供了include標簽幫你重用布局。
例如你現在決定創建一個有一個圖片居中的Toolbar工具欄,然后你想要添加到每個頁面中,下面是Toolbar效果:
下面是batman_toolbar.xml代碼
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/AppTheme.AppBarOverlay"
app:popupTheme="@style/AppTheme.PopupOverlay">
<ImageView android:layout_width="wrap_content"
android:layout_height="@dimen/batman_logo_height"
android:layout_gravity="center"
android:src="@drawable/batman_logo_transparent"/>
</android.support.v7.widget.Toolbar>
你可以復制粘貼這些代碼到每個Activity,但是不要這么做,在編程中有一個重要的規則:當你復制粘貼,那你就是在做錯誤的事。在這種情況下你可以用include標簽在多個界面重用這個布局。
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
android:fitsSystemWindows="true"
android:background="@android:color/white"
tools:context=".MainActivity">
<include layout="@layout/batman_toolbar"/>
</android.support.design.widget.CoordinatorLayout>
用include標簽你可以只用一行代碼在app的每個頁面添加你的toolbar,任何改變都會自動更新到所有頁面。
除了include,merge也常用來從你的view層次結構中減不必要的view,它會移除沒必要的嵌套的layouts,例如,如果被包含布局文件的根是一個LinearLayout,然后你把它include包含在另外一個LinearLayout里面,2個嵌套的LinearLayouts是沒有必要的,這個嵌套的layout沒有任何作用除了影響UI性能。在這種情況下可以用merage來替換被包含布局的根LinarLayout 移除不必要的view.
關于include和merge的更多信息你可以查看官方文檔
Don’t always play by the rules
上面的技巧不用當做規則
我希望這5個技巧可以幫你寫出更好更簡單的布局layout,但是不要把這些技巧當是規則,更像是指南。總有一些情況下你沒法使用這些技巧,只能通過增加布局的復雜性來解決。在這種情況下,在添加更多view之前,你可以考慮自定義View試的找到更簡單的解決方法。只要記住一件事,在你的視圖層次添加一個view代價是不可小噓的,它會影響你的app加載速度。
謝謝Ana和oFca對文章進行校對。
來自:http://blog.csdn.net/tiankong1206/article/details/50479471