Android面試一天一題(Day 42:關(guān)于Android布局你不知道的)

Android常見的5個(gè)布局均践,我想大家一定不會(huì)陌生。LinearLayout、RelativeLayout和FrameLayout也是使用頻率較高的布局方式宋渔,做Android開發(fā)的一定使用過(guò)。

傳統(tǒng)的5種布局方式:

  • LinearLayout
  • RelativeLayout
  • FrameLayout
  • GridLayout
  • TableLayout

不過(guò)我的問題并不是問面試者如何使用這些基礎(chǔ)的布局辜限,而是要看面試者怎么解決布局嵌套(影響性能)和屏幕適配問題皇拣。

面試題:你是如何解決Android的布局嵌套問題的?

我們都清楚Android界面的布局太復(fù)雜薄嫡,嵌套層次過(guò)深氧急,會(huì)使整個(gè)界面的測(cè)量、布局和繪制變得更復(fù)雜毫深,對(duì)性能會(huì)造成影響吩坝。所以我們?cè)趯慙ayout文件時(shí),也要盡量避免布局的嵌套層次過(guò)深的問題哑蔫。

在怎么解決問題之前钉寝,我們得有一個(gè)好方法先判斷當(dāng)前的問題情況。Android SDK工具箱中有一個(gè)叫做Hierarchy Viewer的工具闸迷,能夠在App運(yùn)行時(shí)分析Layout嵌纲。

注意:在ROOT的手機(jī),或者是安裝開發(fā)版的ROM的手機(jī)可以直接使用Hierarchy Viewer腥沽。
如果沒有Root的手機(jī)(SDK 4.1及以上)逮走,需要在你的PC端添加一個(gè)環(huán)境變量“ANDROID_HVPROTO=ddm”。

Mac系統(tǒng)的配置如下:


保存后運(yùn)行:source ~/.bash_profile

最后可以DDMS的Hierarchy Viewer看到:


下面列舉一些面試者常使用的方式今阳。

merge
merge標(biāo)簽的作用是合并UI布局言沐,使用該標(biāo)簽?zāi)芙档蚒I布局的嵌套層次邓嘹。

merge標(biāo)簽可用于兩種情況:

  • 布局頂結(jié)點(diǎn)是FrameLayout且不需要設(shè)置background或padding等屬性,可以用merge代替险胰,因?yàn)锳ctivity內(nèi)容試圖的parent view就是個(gè)FrameLayout汹押,所以可以用merge消除只剩一個(gè)。
  • 某布局作為子布局被其他布局include時(shí)起便,使用merge當(dāng)作該布局的頂節(jié)點(diǎn)棚贾,這樣在被引入時(shí)頂結(jié)點(diǎn)會(huì)自動(dòng)被忽略,而將其子節(jié)點(diǎn)全部合并到主布局中榆综。

ViewStub
ViewStub標(biāo)簽引入的布局默認(rèn)不會(huì)inflate妙痹,既不會(huì)顯示也不會(huì)占用位置。 ViewStub常用來(lái)引入那些默認(rèn)不會(huì)顯示鼻疮,只在特殊情況下顯示的布局怯伊,如數(shù)據(jù)加載進(jìn)度布局、出錯(cuò)提示布局等判沟。

需要在使用時(shí)手動(dòng)inflate:

ViewStub stub = (ViewStub)findViewById(R.id.error_layout);
errorView = stub.inflate();
errorView.setVisibility(View.VISIBLE);

ViewStub在一定的程度可以起到減少嵌套層次的作用耿芹,特別是很多時(shí)候我們的程序可能不需要走到ViewStub的界面。

include
將可復(fù)用的組件抽取出來(lái)并通過(guò)include標(biāo)簽使用挪哄,但<include>標(biāo)簽?zāi)軠p少布局的層次嗎吧秕?

我認(rèn)為不能。include主要解決的是相同布局的復(fù)用問題迹炼,它并不能減少布局的層次砸彬。

用RelativeLayout代替LinearLayout

很多人為了減少布局層次喜歡用RelativeLayout代替LinearLayout,不過(guò)可能達(dá)到的效果并不會(huì)很明顯斯入。層次是減少了砂碉,但本身RelativeLayout就會(huì)比LinearLayout性能差一點(diǎn)。

有一些界面刻两,比如一個(gè)圖片和一個(gè)文本的布局(ListItem常見的布局方式)增蹭,可以利用TextView有drawableLeft, drawableRight等屬性,完全不需要RelativeLayout或者LinearLayout布局闹伪。

你不知道的兩種新的布局方式

傳統(tǒng)的布局方式存在一定的缺陷,如RelativeLayout要兩次測(cè)量(measure)它的子View才能知道確切的高度壮池;如果LinearLayout布局的子View有設(shè)置了layout_weight偏瓤,那么它也需要測(cè)量?jī)纱尾拍塬@得布局的高度。

相對(duì)于傳統(tǒng)的布局方式椰憋,Android官方還推出了兩種新的布局方式:ConstraintLayout和FlexboxLayout厅克。

ConstraintLayout
ConstraintLayout即約束布局,在2016年由Google I/O推出橙依。ConstraintLayout和RelativeLayout有點(diǎn)類似证舟,控件之間根據(jù)依賴關(guān)系而存在硕旗,但比RelativeLayout更加靈活。創(chuàng)建大型復(fù)雜的布局仍然可以使用扁平的層級(jí)(不用嵌套View Group)女责,說(shuō)的簡(jiǎn)單些就是漆枚,再?gòu)?fù)雜的界面也可以只有2層層次。

要使用ConstraintLayout需要在build.gradle中添加相關(guān)的support庫(kù):

compile 'com.android.support.constraint:constraint-layout:1.0.2'

Android Studio 2.3及之后的版本使用引導(dǎo)創(chuàng)建Empty的Activity時(shí)抵知,默認(rèn)就是使用ConstraintLayout布局墙基。關(guān)于本面試題的答案,官方其實(shí)已經(jīng)明確給出信號(hào)了刷喜。


使用ConstraintLayout可以有效的解決布局嵌套過(guò)多導(dǎo)致的性能問題残制,官方也對(duì)其渲染性能進(jìn)行了優(yōu)化,并且ConstraintLayout支持可視化的方式編寫布局掖疮。

不過(guò)學(xué)會(huì)熟練使用ConstraintLayout會(huì)需要一點(diǎn)時(shí)間初茶,但這是值得的。

官方文檔:https://developer.android.com/training/constraint-layout/index.html

FlexBoxLayout
做過(guò)前端開發(fā)(CSS方面)的同學(xué)對(duì)FlexBox一定不會(huì)陌生浊闪,最近我在做微信小程序開發(fā)時(shí)也涉及到FlexBox恼布。FlexBox(彈性布局)是w3c在2009年提出的一種新的布局方案,解決以前那種傳統(tǒng)css的盒模型的局限性规揪。

Google開源了FlexboxLayout布局和前端CSS FlexBox布局具有相同的功能(肯定有不一樣的地方)桥氏,但已經(jīng)足夠在Android上改進(jìn)布局的構(gòu)建方式。

項(xiàng)目地址:https://github.com/google/flexbox-layout

FlexBoxLayout可以理解成一種更高級(jí)的LinearLayout猛铅,不過(guò)比LinearLayout更加強(qiáng)大和靈活字支。如果我們使用LinearLayout布局的話,那么不同的分辨率奸忽,也許我們要重新調(diào)整布局堕伪,勢(shì)必會(huì)需要跟多的布局文件放在不同的資源目錄。而使用FlexBoxLayout來(lái)布局的話栗菜,它可以適應(yīng)各種界面的改變(所以叫響應(yīng)式布局)欠雌。

看一下官方圖片感受一下:


如果對(duì)前端的Flexbox不太了解的話,你還需要補(bǔ)一些概念疙筹,好在這些東西在網(wǎng)上很容易找到富俄。

小結(jié)

可能很多讀者會(huì)覺這樣的面試題是吹毛求疵,很多項(xiàng)目中哪有這么復(fù)雜的界面而咆,根本就用不到這些優(yōu)化措施霍比。

So,你沒有成長(zhǎng)為厲害的人暴备。

可以說(shuō)厲害的人悠瞬,或者叫高手,可能只是比較多在意這些細(xì)節(jié)而已。在實(shí)踐中的經(jīng)歷告訴我浅妆,很多難于解決的性能問題望迎,并不是因?yàn)橛幸粋€(gè)影響性能的問題無(wú)法攻克,而是沒有一個(gè)明顯的制約因素凌外,是有各種小問題一點(diǎn)一點(diǎn)堆積起來(lái)辩尊,最終積重難返。

所以趴乡,把細(xì)節(jié)做好对省,或者意識(shí)到細(xì)節(jié)的地方可能引發(fā)的問題,對(duì)我們解決問題是很有幫助的晾捏,不要浪費(fèi)了讓你可以成長(zhǎng)的細(xì)節(jié)蒿涎。


相關(guān)閱讀:

Android面試一天一題(Day 37:一套高級(jí)工程師的面試題)
Android面試一天一題(Day 30:老外的自定義View面試題)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惦辛,隨后出現(xiàn)的幾起案子劳秋,更是在濱河造成了極大的恐慌,老刑警劉巖胖齐,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玻淑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡呀伙,警方通過(guò)查閱死者的電腦和手機(jī)补履,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)剿另,“玉大人箫锤,你說(shuō)我怎么就攤上這事∮昱” “怎么了谚攒?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)氛堕。 經(jīng)常有香客問我馏臭,道長(zhǎng),這世上最難降的妖魔是什么讼稚? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任括儒,我火速辦了婚禮,結(jié)果婚禮上锐想,老公的妹妹穿的比我還像新娘帮寻。我一直安慰自己,他們只是感情好痛倚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布规婆。 她就那樣靜靜地躺著澜躺,像睡著了一般蝉稳。 火紅的嫁衣襯著肌膚如雪抒蚜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天耘戚,我揣著相機(jī)與錄音嗡髓,去河邊找鬼。 笑死收津,一個(gè)胖子當(dāng)著我的面吹牛饿这,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播撞秋,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼长捧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了吻贿?” 一聲冷哼從身側(cè)響起串结,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舅列,沒想到半個(gè)月后肌割,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帐要,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年把敞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榨惠。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奋早,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出冒冬,到底是詐尸還是另有隱情伸蚯,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布简烤,位于F島的核電站剂邮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏横侦。R本人自食惡果不足惜挥萌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枉侧。 院中可真熱鬧引瀑,春花似錦、人聲如沸榨馁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至屑柔,卻和暖如春屡萤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背掸宛。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工死陆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唧瘾。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓措译,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親饰序。 傳聞我的和親對(duì)象是個(gè)殘疾皇子领虹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容