Android布局優(yōu)化

????作為android應(yīng)用來講,無論應(yīng)用本身多么美觀,功能多么強大,內(nèi)容多么豐富。但如果App本身打開界面緩慢超過手機16ms刷新一次頁面的時間,就會產(chǎn)生卡頓。用戶體驗都會變得極差,導(dǎo)致用戶量減少。所以我們在開發(fā)過程中同樣要注重布局優(yōu)化。

<include>標(biāo)簽

????在Layout布局中如果有你想要引用的布局時,若該布局在不同的布局是公共布局,我們會多次使用到。這時可以使用<include>標(biāo)簽。并且便于統(tǒng)一的修改與查看。

    <-- container為引用布局的布局id -->
    <include layout="@layout/container"/>

????非常簡單只要在你所需要放置該布局的布局內(nèi)部使用<include>標(biāo)簽引入該布局就可以了。
在<include>標(biāo)簽當(dāng)中,我們是可以覆寫所有l(wèi)ayout屬性的,即include中指定的layout屬性將會覆蓋掉。如我們想修改它的寬高為wrap_content

    <include  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        layout="@layout/container" />  

????除了layout_width與layout_height之外,我們還可以覆寫container中的任何一個layout屬性,如layout_gravity、layout_margin等,而非layout屬性則無法在<include>標(biāo)簽當(dāng)中進行覆寫。另外需要注意的是,如果我們想要在<include>標(biāo)簽當(dāng)中覆寫layout屬性,必須要將layout_width和layout_height這兩個屬性也進行覆寫,否則覆寫效果將不會生效。

<merge>標(biāo)簽

????<merge>標(biāo)簽是作為<include>標(biāo)簽的一種輔助擴展來使用的,它的主要作用是為了防止在引用布局文件時產(chǎn)生多余的布局嵌套。Android解析和展示一個布局需要消耗時間,布局嵌套的越多,那么解析起來也就越耗時,性能也就越差,因此我們在編寫布局文件時應(yīng)該讓嵌套的層數(shù)越少越好。

    <merge  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content" >
        <View  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"/>
        <View  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"/>
    </merge>

????大家可以見到<merge>標(biāo)簽的使用方法是直接當(dāng)做該布局的根布局節(jié)點使用,而當(dāng)在其他位置需要引用該布局時,則使用<include>標(biāo)簽進行引用,同時該節(jié)點會同步變成父容器的根節(jié)點。比如你使用在LinearLayout中則兩個view線性排列,而在RelativeLayout中則<merge>標(biāo)簽就相當(dāng)于相對布局標(biāo)簽。這樣就可以省略一些不必要的布局嵌套了。

<ViewStub>標(biāo)簽

????<ViewStub>標(biāo)簽實際上是一個輕量級的View,它既沒有尺寸,也不會繪制任何東西,所以將它放置在布局當(dāng)中基本可以認為是完全不會影響性能的。只要在需要的時候顯示它,才會進行加載。

<ViewStub
    android:id="@+id/stub"
    android:inflatedId="@+id/container_layout"
    android:layout="@layout/stub_layout"
    android:layout_width=",match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom" />

????雖然ViewStub是不占用任何空間的,但是每個布局都必須要指定layout_width和layout_height屬性,否則運行就會報錯。且ViewStub所要替代的layout文件中不能含有<merge>標(biāo)簽,所以使用前需要構(gòu)思好界面布局,以免不必要的嵌套。一旦ViewStub被顯示后,則ViewStub將從視圖框架中移除,其id也會失效,此時findViewById()得到的也是空的。
????ViewStub使用起來非常簡單,只要在需要的時候findViewById()招到它并調(diào)用setVisibility(View.VISIBLE)或者inflate()顯示它就可以了。

標(biāo)簽小結(jié)

標(biāo)簽 使用原因 優(yōu)化結(jié)果 使用舉例
<include> 提取公共部分,提高布局復(fù)用性 減少測量,繪制時間 App中有多個UI界面需要使用同一布局或部分布局時。如頁面標(biāo)題toolBar復(fù)用時使用。
<merge> 布局層級減少 減少繪制工作量 當(dāng)所需要復(fù)用的部分布局與要合并到的布局的根標(biāo)簽一致時使用。(類似加強版include,減少布局層級,但耦合性更強)。
<ViewStub> 無需第一時間展示于界面上,在需要時加載 減少測量,繪制時間 該界面不需要第一時間展示給用戶,如網(wǎng)絡(luò)報錯界面,或用戶信息下拉界面,在該界面中,但第一時間不需要顯示給用戶時使用。

ConstraintLayout約束布局

布局可視化操作.png

????AndroidStudio上有一個神奇的功能,就是在Xml布局中我們可以在design標(biāo)簽下進行布局可視化操作。但是該功能并不完善,屬于系統(tǒng)自動生成的一個布局,反而會讓布局內(nèi)部凌亂不堪,難以讀懂,同時會造成卡頓,所以以前我們都是用該界面進行預(yù)覽查看;而ConstraintLayout約束布局這一新布局,它反而支持布局可視化操作,可以把它比喻成一個可視化視圖操作布局的RelativeLayout,ConstraintLayout是使用約束的方式來指定各個控件的位置和關(guān)系的。布局內(nèi)部不需要嵌套其他布局,就可以完成你想要的界面出現(xiàn)。所以它可以有效的避免布局的嵌套,從而達到優(yōu)化布局的效果。因為使用太過復(fù)雜,想要深入了解使用方法請點擊ConstraintLayout。

減少視圖樹層級結(jié)構(gòu)

????系統(tǒng)在顯示沒一個視圖的時候,都要經(jīng)理測量,布局,繪制的過程。如果我們的布局嵌套層數(shù)太多,會導(dǎo)致額外的測量、布局等,十分消耗系統(tǒng)資源,使UI卡頓,影響用戶體驗。所以要盡量減少是圖書層級結(jié)構(gòu),避免不必要的布局嵌套,使用更少嵌套的布局方式。


DDMS.png

????查看文件的視圖樹,我們可以使用DDMS來查看。首先運行項目在真機或虛擬機上。而后再到tools中打開DDMS。這里就不展開介紹了。

其他

  • 嵌套的LinearLayout中,盡量不要使用weight,因為weight會重新測量兩次。
  • Layout的選擇,以盡量減少View樹的層級為主,去除不必要的嵌套和View節(jié)點。比如如果LinearLayout嵌套過多,建議使用RelativeLayout減少布局嵌套。
  • RelativeLayout本身盡量不要嵌套使用。
  • View視圖的隱藏與現(xiàn)實,盡量使用invisible。因為gone,不占用空間,視圖會重新測量繪制;而invisible視圖不會重新繪制,但仍然占用空間位置。
  • 布局調(diào)優(yōu)工具:hierarchy viewer,Lint tool
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容