gogo专业大尺度亚洲高清人体,美女张开双腿让男生桶,亚洲av无码一区二区三区鸳鸯影院,久久久久国产精品人妻

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 性能優(yōu)化之布局文件優(yōu)化

性能優(yōu)化之布局文件優(yōu)化 時(shí)間:2018-09-26      來源:未知

隨著android手機(jī)的迅速發(fā)展以及技術(shù)的更新,市場對(duì)應(yīng)用的性能提出了更高的要求,android圖形界面是用戶直接的感受渠道,因此做好UI界面的設(shè)計(jì)日益重要。而其實(shí)相同的布局效果可以有不同的實(shí)現(xiàn)方式。糟糕的布局會(huì)使程序加載UI的速度非常慢,從而降低了用戶體驗(yàn)滿意度,同時(shí)也對(duì)程序的性能產(chǎn)生比較大的影響,因此優(yōu)化布局是提高性能的一種重要途徑,以下從三方面講述布局的三重優(yōu)化。

第一重優(yōu)化:布局中樣式的抽取

布局文件中,系統(tǒng)給我們提供了很多控件的屬性,我們可以方便的使用,但有時(shí)在同一個(gè)布局中甚至不同的布局中會(huì)重復(fù)出現(xiàn)同一個(gè)控件并且其屬性設(shè)置相似,這時(shí)如果我們重復(fù)的單個(gè)定義相同控件的屬性會(huì)使布局代碼顯得龐大冗雜,減低了布局文件的可讀性同時(shí)開發(fā)的效率和程序性能也會(huì)受很大的影響,這就需要我們將相同控件的相同屬性抽取出來做成樣式模板。

舉例1:

同一個(gè)布局或不同布局文件中常常會(huì)用到控件顯示文字比如TextView,Button等,而這時(shí)候?qū)τ诳丶拇笮〖帮@示的文字的大小和顏色等要求又是相同的,這時(shí)我們就可以將這些相同的屬性抽取出來。如下圖布局是一個(gè)簡單的LinearLayout布局中的三個(gè)控件中間一個(gè)Button,兩邊各一個(gè)TextView,看代碼不難發(fā)現(xiàn)他們的尺寸,背景,和字體大小顏色都是相同的,這時(shí)我們則可以抽取出來。

將控件相同的樣式抽取到values文件夾下的style.xml文件中如下圖紅色圈住部分:

抽取之后,布局文件中我們只需引入此樣式即可,如果其他控件有個(gè)別屬性不同,則只需在布局文件中重寫此屬性,系統(tǒng)會(huì)自動(dòng)將布局文件中的屬性覆蓋抽取出的style屬性,如下圖:

此時(shí)布局則大大簡化,效果則完全相同,如下圖:

第二重優(yōu)化:布局文件復(fù)用

布局文件的復(fù)用思想和樣式抽取的思想是相同的,都是將相同的東西抽取出來以達(dá)到可以重復(fù)利用的目的。當(dāng)然Android也已經(jīng)充分考慮到了布局重用的重要性,于是提供了這兩個(gè)非常有用的標(biāo)簽,讓我們更方便的實(shí)現(xiàn)代碼復(fù)用。

1.<include>

<include>標(biāo)簽可以允許在一個(gè)布局當(dāng)中引入另外一個(gè)布局,那么比如說我們程序的所有界面都有一個(gè)公共的部分,這個(gè)時(shí)候好的做法就是將這個(gè)公共的部分提取到一個(gè)獨(dú)立的布局文件當(dāng)中,然后在每個(gè)界面的布局文件當(dāng)中來引用這個(gè)公共的布局。

舉例2:我們應(yīng)該都知道,目前幾乎所有的軟件都會(huì)有一個(gè)頭布局,頭布局中可以包含界面的標(biāo)題、返回按鈕、以及其它一些操作功能等。那這樣的一個(gè)頭布局,有些軟件是使用ActionBar來實(shí)現(xiàn)的,但是由于ActionBar的靈活性不太好,因而也有很多軟件會(huì)選擇自己去編寫實(shí)現(xiàn)。那如果自己去實(shí)現(xiàn)的話,由于這個(gè)頭布局是在所有界面都要使用的,顯然我們不可能在每個(gè)界面當(dāng)中都去寫一遍這個(gè)頭布局的代碼,因此這種情況下使用標(biāo)簽就非常合適了。這里為了給大家演示一下,我就編寫一個(gè)非常簡單的頭布局,在res/layout文件夾中新建titlebar.xml作為頭布局,代碼如下所示:

titlebar.xml中的布局非常簡單,外層RelativeLayout里面只有兩個(gè)Button和一個(gè)TextView,左邊Button用于實(shí)現(xiàn)返回功能,右邊的Button用于實(shí)現(xiàn)完成功能,中間的TextView則可以用于顯示當(dāng)前界面的標(biāo)題。我們可以來預(yù)覽一下titlebar的樣子,如下圖所示:

titlebar的布局寫完,接下來就可以對(duì)布局文件進(jìn)行復(fù)用了,無論任何界面需要加入titlebar這個(gè)功能,只需要在布局文件中引入titlebar.xml就可以了。比如我們的程序當(dāng)中有一個(gè)activity_main.xml文件,現(xiàn)在想要引入titlebar,布局文件只需要這樣寫:

這樣就非常簡單,一行include語句就搞定了,而無需重復(fù)寫titlebar里的布局。標(biāo)簽當(dāng)中可以指定一個(gè)layout屬性,我們?cè)谶@個(gè)layout屬性中填寫需要引入的布局名就可以了。而且使用這種引入的方式,以后如果titlebar的界面有所變更,我們只需要修改titlebar.xml這一個(gè)文件就可以了,而不是所有界面一個(gè)個(gè)地去修改。但需要注意的是雖然titlebar是成功引入了,但是我們activity_main.xml中本來的界面全部都不見了!出現(xiàn)這個(gè)問題的原因是因?yàn)閠itlebar的外層布局是一個(gè)寬高都是match_parent的RelativeLayout,它會(huì)將整個(gè)布局都填充滿,因而我們?cè)镜牟季忠簿涂床灰娏。那既然問題的原因清楚了,相信你立刻就想到應(yīng)該怎么修改了,將RelativeLayout的layout_height屬性修改成wrap_content不就可以了嘛。沒錯(cuò),這樣修改當(dāng)然是沒問題的,不過這種修改方式會(huì)讓所有引用titlebar的界面都受到影響,而如何你只希望讓activity_main.xml這一個(gè)界面受影響的話,那么可以使用覆寫屬性的方式。

標(biāo)簽當(dāng)中,我們是可以覆寫所有l(wèi)ayout屬性的,即include中指定的layout屬性將會(huì)覆蓋掉titlebar中指定的layout屬性。因此,這里我們希望將titlebar的高度設(shè)置成wrap_content,就可以這樣寫:

這時(shí)重新運(yùn)行一下則是可以正常顯示titlebar之外的其他內(nèi)容的。

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

2.<merge>

<merge>標(biāo)簽是作為標(biāo)簽的一種輔助擴(kuò)展來使用的,他的主要作用是為了防止在引用布局文件時(shí)產(chǎn)生多余的布局嵌套。Android去解析和展示一個(gè)布局是需要消耗時(shí)間的,布局嵌套越多解析起來越是耗時(shí),性能也就越差,因此我們?cè)诰帉懖季治募䲡r(shí)應(yīng)該讓嵌套的層數(shù)越少越好。

有優(yōu)點(diǎn),但是它也存在著一個(gè)不好的地方,就是可能會(huì)導(dǎo)致產(chǎn)生多余的布局嵌套。這里還是通過舉例的方式跟大家說明一下,比如說我們需要編寫一個(gè)確定取消按鈕的公共布局,這樣任何一個(gè)界面需要確定和取消功能時(shí)就不用再單獨(dú)編寫了,新建ok_cancel_layout.xml,代碼如下所示:

可以看到,這個(gè)界面也是非常簡單,外層是一個(gè)水平方向LinearLayout,LinearLayout中包含了兩個(gè)按鈕,一個(gè)用于實(shí)現(xiàn)確定功能,一個(gè)用于實(shí)現(xiàn)取消功能,F(xiàn)在我們可以來預(yù)覽一下這個(gè)界面,如下圖所示:

然后我們有一個(gè)profile.xml的界面需要編輯一些內(nèi)容,那么這里就可以將ok_cancel_layout這個(gè)布局引入到profile.xml界面當(dāng)中,如下所示:

運(yùn)行效果如圖:

這個(gè)看上去并沒有什么不對(duì),可是在你毫無察覺的情況下,目profile.xml這個(gè)界面當(dāng)中其實(shí)已經(jīng)存在著多余的布局嵌套了!感覺還沒寫幾行代碼呢,怎么這就已經(jīng)有多余的布局嵌套了?我們可以通過View Hierarchy工具來查看一下,如下圖所示:

可以看到,外層首先是一個(gè)FrameLayout,然后FrameLayout中包含的是一個(gè)LinearLayout,這個(gè)就是我們?cè)趐rofile.xml中定義的外層布局。接下來的部分就有問題了,在外層的LinearLayout當(dāng)中包含了兩個(gè)元素,一個(gè)是EditText,另一個(gè)又是一個(gè)LinearLayout,然后在這個(gè)內(nèi)部的LinearLayout當(dāng)中才包含了確定和取消這兩個(gè)按鈕。這個(gè)內(nèi)部的LinearLayout就是一個(gè)多余的布局嵌套,實(shí)際上并不需要這樣一層,讓兩個(gè)按鈕直接包含在外部的LinearLayout當(dāng)中就可以了。而這個(gè)多余的布局嵌套其實(shí)就是由于布局引入所導(dǎo)致的,因?yàn)槲覀冊(cè)趏k_cancel_layout.xml中也定義了一個(gè)LinearLayout。那么應(yīng)該怎樣優(yōu)化掉這個(gè)問題呢?當(dāng)然就是使用標(biāo)簽來完成了,修改ok_cancel_layout.xml中的代碼,如下所示:

可以看到,這里我們將ok_cancel_layout外層的LinearLayout布局刪除掉,換用了標(biāo)簽,這就表示當(dāng)有任何一個(gè)地方去include這個(gè)布局時(shí),會(huì)將標(biāo)簽內(nèi)包含的內(nèi)容直接填充到include的位置,不會(huì)再添加任何額外的布局結(jié)構(gòu)。好的,的用法就是這么簡單,現(xiàn)在重新運(yùn)行一下程序,你會(huì)看到界面沒有任何改變,然后我們?cè)偻ㄟ^View Hierarchy工具來查看一下當(dāng)前的View結(jié)構(gòu),如下圖所示:

第三重優(yōu)化:僅在需要時(shí)才加載布局

有的時(shí)候我們會(huì)遇到這樣的場景,就是某個(gè)布局當(dāng)中的元素非常多,但并不是所有元素都一起顯示出來的,而是普通情況下只顯示部分常用的元素,而那些不常用的元素只有在用戶進(jìn)行特定操作的情況下才會(huì)顯示出來。

這里舉個(gè)大家都非常熟悉的例子,我們?cè)谔砑勇?lián)系人的時(shí)候其實(shí)可以編輯的字段真的非常多,姓名、電話、email、傳真、住址、昵稱等等等等,但其實(shí)基本上大家常用的就是填一個(gè)姓名,填一個(gè)電話而已。那么將這么多繁雜的字段都一起顯示在界面上其實(shí)并不是一種很好的做法,因?yàn)榇蠖鄶?shù)人都是用不到這些字段的。比較聰明的做法就是把常用的姓名和電話顯示在界面上,然后給用戶提供一個(gè)添加更多字段的選項(xiàng),當(dāng)用戶真的有需要去添加其它信息的時(shí)候,我們才將另外的元素顯示到界面上。

說到實(shí)現(xiàn)這樣一個(gè)功能,我相信大多數(shù)人的第一反應(yīng)就是將不常用的元素使用INVISIBLE或者GONE進(jìn)行隱藏,然后當(dāng)用戶需要使用這些元素的時(shí)候再把它們置成VISIBLE顯示出來。使用這種方式肯定可以實(shí)現(xiàn)功能的,但是性能方面就表現(xiàn)得一般了,因?yàn)榧词故菍⒃剡M(jìn)行隱藏,它們其實(shí)還是在布局當(dāng)中的,每個(gè)元素還擁有著自己的寬、高、背景等等屬性,解析布局的時(shí)候也會(huì)將這些隱藏的元素一一解析出來。

那么我們?nèi)绾尾拍茏屵@些不常用的元素僅在需要時(shí)才去加載呢?Android為此提供了一種非常輕量級(jí)的控件,ViewStub。ViewStub雖說也是View的一種,但是它沒有大小,沒有繪制功能,也不參與布局,資源消耗非常低,將它放置在布局當(dāng)中基本可以認(rèn)為是完全不會(huì)影響性能的。

下面我們就來學(xué)習(xí)一下如何使用ViewStub來完成僅在需要時(shí)才去加載布局的功能,目前profile.xml中只有一個(gè)EditText用于編輯信息,那么比如說我們還有另外三個(gè)不太常用的EditText,就可以將它們定義在另外一個(gè)布局文件當(dāng)中。新建profile_extra.xml文件,代碼如下所示:

運(yùn)行效果如圖:

目前profile_extra.xml是一個(gè)獨(dú)立的布局,和profile.xml這個(gè)布局文件是完全沒有關(guān)系的。接下來我們修改profile.xml文件中的代碼,如下所示:

可以看到LinearLayout布局中我們新增了一個(gè)More Button,這個(gè)按鈕就是用于去加載那些不常用的元素的,然后在Button的下面定義了一個(gè)ViewStub。在ViewStub控件中,我們先是通過id屬性給它指定了一個(gè)唯一標(biāo)識(shí),又通過layout屬性將profile_extra布局傳入進(jìn)來,接著給ViewStub指定了一個(gè)寬高。注意,雖然ViewStub是不占用任何空間的,但是每個(gè)布局都必須要指定layout_width和layout_height屬性,否則運(yùn)行就會(huì)報(bào)錯(cuò)。

接著修改ProfileActivity中的代碼,在Activity中添加More Button的點(diǎn)擊事件,并在點(diǎn)擊事件中進(jìn)行如下邏輯處理:

當(dāng)點(diǎn)擊More Button之后我們首先會(huì)調(diào)用findViewById()方法將ViewStub的實(shí)例獲取到,拿到ViewStub的實(shí)例之后就很簡單了,調(diào)用inflate()方法或者setVisibility(View.VISIBLE)都可以將隱藏的布局給加載出來,而加載的這個(gè)布局就是剛才在XML當(dāng)中配置的profile_extra布局。

調(diào)用inflate()方法之后會(huì)將加載出來的布局進(jìn)行返回,之后我們就可以對(duì)這個(gè)布局進(jìn)行任意的操作了,再次隱藏顯示,或者獲取子元素的實(shí)例等。注意這里我對(duì)ViewStub的實(shí)例進(jìn)行了一個(gè)非空判斷,這是因?yàn)閂iewStub在XML中定義的id只在一開始有效,一旦ViewStub中指定的布局加載之后,這個(gè)id也就失敗了,那么此時(shí)findViewById()得到的值也會(huì)是空。

運(yùn)行結(jié)果如圖所示:

可以看到,界面上只有一個(gè)More按鈕,ViewStub是完全不占用任何空間的。然后點(diǎn)擊一下More按鈕,新的界面如下所示:

運(yùn)行結(jié)果正常,profile_extra.xml中定義的布局已經(jīng)加載出來了,而且顯示的位置正是ViewStub控件定義的位置,說明我們已經(jīng)成功是實(shí)現(xiàn)了ViewStub的功能。但是需要注意的是ViewStub所加載的布局不能使用標(biāo)簽,也就是說包含ViewStub控件的布局在進(jìn)行復(fù)用時(shí)會(huì)導(dǎo)致加載出來的布局存在著多余的嵌套結(jié)構(gòu),但是對(duì)于含有較多隱藏子布局的布局文件來說,使用ViewStub還是一種相當(dāng)不錯(cuò)的選擇的,即使增加了一層無用的布局結(jié)構(gòu),仍然還是利大于弊,具體如何去選擇就要具體情況具體分析了。對(duì)于性能的優(yōu)化需要考慮很多的方面,這里只是簡單的介紹了性能優(yōu)化中的布局優(yōu)化,作為一個(gè)開發(fā)者還需要有的放矢的選擇和權(quán)衡各種方法對(duì)應(yīng)用性能的影響,從而開發(fā)出性能優(yōu)越,客戶滿意度高的應(yīng)用。

上一篇:二維數(shù)組與行指針

下一篇:Node.js介紹和環(huán)境的安裝方式

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5,京公海網(wǎng)安備11010802025203號(hào)

回到頂部