本文主要記錄Android布局優(yōu)化的一些小技巧
Android中雪猪,如果一個View樹的高度太高,就會嚴重影響測量渤刃,布局和繪制的速度拥峦,因此可以使用一些方法來降低View樹的高度,提高用戶體驗
目錄
- 避免使用過多嵌套
- 重用布局文件<include>卖子、<merge>
- View延時加載<ViewStub>
- 工具HierarchyView幫助優(yōu)化布局(本文沒有介紹具體使用)
避免使用過多嵌套
先來看一個非常常見的效果
相信這樣的效果對我們來說完全不是問題略号,然而很多人會這樣寫布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="第一項"
android:textSize="18sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/arrows_right" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#cccccc" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="第二項"
android:textSize="18sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/arrows_right" />
</LinearLayout>
</LinearLayout>
可以看到這里布局嵌套了多層,類似這種效果有更優(yōu)雅的寫法洋闽,效果是完全一樣的
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@drawable/spacer"
android:orientation="vertical"
android:showDividers="middle">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@mipmap/ic_launcher"
android:drawablePadding="10dp"
android:drawableRight="@drawable/arrows_right"
android:gravity="center_vertical"
android:padding="5dp"
android:text="第一項"
android:textSize="18sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@mipmap/ic_launcher"
android:drawablePadding="10dp"
android:drawableRight="@drawable/arrows_right"
android:gravity="center_vertical"
android:padding="5dp"
android:text="第二項"
android:textSize="18sp" />
</LinearLayout>
這里主要用到了LinearLayout的android:divider="@drawable/spacer"
和android:showDividers="middle"
兩個屬性添加分割線玄柠,注意android:divider
里面的參數(shù)必須是shape
類型才能顯示。TextView里面則用到了android:drawableLeft="@mipmap/ic_launcher"
設置文字左邊圖片诫舅,android:drawableRight="@drawable/arrows_right"
同理這是文字右邊圖片羽利,android:drawablePadding="10dp"
設置圖片與文字的間距。
我們可以對比一下兩個布局文件刊懈,更少的嵌套这弧,更簡潔的代碼,相信你會更喜歡第二種寫法虚汛。
重用布局文件<include>匾浪、<merge>
<include>
簡單來說<include>
標簽就是為了一些通用的UI來使用的,有時候我們不想用系統(tǒng)的Toolbar卷哩,完全可以自己寫一個滿足我們的需求蛋辈,先看效果。
這里很簡單的實現(xiàn)了左邊一個圖片将谊,中間標題冷溶,右邊一個圖片,一般情況左邊是一個back按鈕瓢娜,右邊一個action按鈕挂洛,這里為了方便演示就直接用系統(tǒng)里的圖片。關鍵代碼片段如下眠砾。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@drawable/spacer"
android:orientation="vertical"
android:showDividers="middle">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:padding="5dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="標題"
android:textSize="18sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
...
</LinearLayout>
由于我們會在多個Activity使用到這個布局虏劲,你完全可以每個Activity都拷貝一份上面的代碼托酸,但我相信身為程序猿的你不會那么做,因為如果某一天需求需要改動這個布局柒巫,而你每個Activity都需要修改励堡,這時候你是崩潰的。為解決此問題我們就可以用到<include>
標簽來重用此UI堡掏。
首先我們可以新建一個top_view.xml
布局文件应结,代碼就是把上面<RelativeLayout>包含的整個提取出來。然后把剛剛的布局替換成<include>
泉唁。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@drawable/spacer"
android:orientation="vertical"
android:showDividers="middle">
<include layout="@layout/top_view" />
...
</LinearLayout>
使用layout="@layout/top_view"
屬性將我們剛剛的布局引入即可鹅龄。非常簡便,這樣即使需要改動我們只需修改top_view.xml
里面的內(nèi)容就能適用整個APP亭畜。
<merge>
簡單來說<merge>
標簽可以有效的減少多余的布局嵌套扮休,這里簡單的舉個栗子。直接貼關鍵代碼
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<include layout="@layout/ok_cancel_layouy" />
</LinearLayout>
ok_cancel_layouy.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ok" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="cancel" />
</LinearLayout>
這時候我們看下View的層次拴鸵,拋開最外層的FrameLayout不說玷坠,先是LinearLayout接著是<include>
里面的LinearLayout,最后是兩個Button劲藐,這時候內(nèi)層的LinearLayout其實是多余的八堡,我們可以使用<merge>
來代替,這樣系統(tǒng)就會忽略<merge>
直接放下兩個Button聘芜。
修改后的ok_cancel_layouy.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ok" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="cancel" />
</merge>
View延時加載<ViewStub>
上面我們知道了通過<include>
可以引用通用UI兄渺,還可以使用<ViewStub>
來引用并實現(xiàn)延遲加載。<ViewStub>
是一個非常輕量級的控件汰现,它沒有大小溶耘,沒有繪制,也不參與布局服鹅。填寫資料的時候,有時會有更多資料填寫百新,這時候我們需要實現(xiàn)點擊更多才顯示其他資料企软,效果如下
點擊more的時候會多出兩個輸入框
布局文件如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:hint="name" />
<ViewStub
android:id="@+id/view_stub"
android:layout_width="match_parent"
android:layout="@layout/more_layout"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_more"
android:layout_width="wrap_content"
android:text="more"
android:layout_height="wrap_content" />
</LinearLayout>
more_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et_more1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="more1" />
<EditText
android:id="@+id/et_more2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:hint="more2" />
</LinearLayout>
點擊more進行顯示
btn_more = (Button) findViewById(R.id.btn_more);
btn_more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ViewStub viewStub = (ViewStub) findViewById(R.id.view_stub);
1.viewStub.setVisibility(View.VISIBLE);
if (viewStub != null) {
2.View inflatedView = viewStub.inflate();
et_more1 = (EditText) inflatedView.findViewById(R.id.et_more1);
et_more2 = (EditText) inflatedView.findViewById(R.id.et_more2);
}
}
});
有兩種方法可以讓<ViewStub>
的布局進行顯示,一種是直接設置viewStub.setVisibility(View.VISIBLE)
饭望,第二種則是使用inflate
來加載仗哨,如要獲取到里面控件,我們一般采用第二種方法铅辞。
從上面可以看出<ViewStub>
的用法類似于<include>
厌漂,不同的是<ViewStub>
必須指定layout_width
和layout_height
屬性,還有一點需要注意<ViewStub>
所加載的布局是不可以使用<merge>
標簽的斟珊。
對于Android布局優(yōu)化就寫這些苇倡,另外系統(tǒng)還提供了一個工具HierarchyView
可以幫助我們更好的優(yōu)化布局,需要學習更多的可以直接閱讀官網(wǎng)的文章。(需要科學上網(wǎng))
第一次寫文章旨椒,有疑問或錯誤的歡迎指出晓褪,互相學習。