android布局優(yōu)化的目標:
- 使屏幕繪制低延遲
- 保證流程穩(wěn)定的幀率來避免卡頓
優(yōu)化布局的技巧:
- 減少布局層次
下圖是一個簡單的app View,其中包含一些View。搭建這些view的時候,一定要留意屏幕右上角的組件樹(Component Tree)。套嵌的子view越深,組件樹就越復雜,渲染起來也就越費時間。

對于app里的每一個view,android系統(tǒng)都會經(jīng)過三部曲來渲染:measure,layout,draw??梢栽谀X中回想下你搭建的view的xml布局文件結構,measure從最頂部的節(jié)點開始,順著layout樹形結構依次往下:測量每個view需要在屏幕當中展示的尺寸大小。每個子節(jié)點都需要向自己的父節(jié)點提供自己的尺寸來決定展示的位置,遇到?jīng)_突的時候,父節(jié)點可以強制子節(jié)點重新measure(由此可能導致measure的時間消耗為原來的2-3倍)。這就是為什么扁平的view結構會性能更好。節(jié)點所處位置越深,套嵌帶來的measure越多,計算就會越費時。
- 刪除無用布局
- 不要嵌套多個使用layout_weight屬性的LinearLayout
- Android lint
- Hierarchy Viewr
-
<merge />
什么情況考慮使用Merge?
子視圖不需要指定任何針對父視圖的布局屬性,例子中TextView僅僅需要直接添加到父視圖上用于顯示就行。例子:
<RelativeLayout
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="com.kevinwang.test.TestActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="Test Merge!"/>
</RelativeLayout>
圖1是使用RelativLayout時顯示的層次結構。

圖1
布局文件修改內(nèi)容如下:
<merge
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="com.kevinwang.test.TestActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="Test Merge!"/>
</merge>
圖2是使用merge時顯示的層次結構。

圖2
Merge標簽有什么使用限制?
只能作為XML布局的根標簽使用。
- ViewStub標簽
ViewStub 是一個隱藏的,不占用內(nèi)存空間的視圖對象,它可以在運行時延遲加載布局資源文件。例子:
先來創(chuàng)建一個Activity中使用的布局文件,文件名是:activity_test.xml
<LinearLayout
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="com.kevinwang.test.TestActivity">
<Button
android:id="@+id/show_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="顯示"/>
<ViewStub
android:id="@+id/viewstub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout="@layout/sub_layout"
/>
<Button
android:id="@+id/hide_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="隱藏"/>
</LinearLayout>
android:layout="@layout/sub_layout"引入一個新的布局sub_layout.xml代碼如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ViewStub中包含的TextVeiw"/>
</LinearLayout>
添加Button點擊事件:
public class TestActivity extends Activity {
private Button showButton;
private Button hideButton;
private ViewStub viewStub;
private View view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
viewStub = (ViewStub) findViewById(R.id.viewstub);
showButton = (Button)findViewById(R.id.show_button);
showButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (view == null) {
view = viewStub.inflate();//注意inflate方法不能被調(diào)用兩次
}
else {
view.setVisibility(View.VISIBLE);
}
}
});
hideButton =(Button)findViewById(R.id.hide_button);
hideButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.setVisibility(View.GONE);
if (view == null) {
Log.i("hide_layout", "隱藏布局已經(jīng)消失");
}
}
});
}
}
打開應用時界面如下圖:

點擊顯示按鈕時界面如下:

點擊隱藏恢復打開應用時的界面
關于布局優(yōu)化更多內(nèi)容可參考MrPeakTech