我使用duilib快3個(gè)月了,總體感覺duilib的使用還是較為簡單的,只是剛?cè)腴T時(shí)可能有些摸不清頭腦。今天寫一篇關(guān)于duilib的入門日志,大致說一下duilib中的各個(gè)布局的作用,以及很關(guān)鍵的相對(duì)布局與絕對(duì)布局的意義與用法。希望可以幫到使用duilib的新手朋友們。duilib高手就可以直接省略這篇文章了!
我剛使用duilib的時(shí)候非常依賴duilib自帶的設(shè)計(jì)器,用他可以拖拉控件,可視化的做出自己想要的界面。可是用一段時(shí)間就會(huì)發(fā)現(xiàn)原帶的設(shè)計(jì)器有很多bug,時(shí)不時(shí)會(huì)崩潰,支持的控件數(shù)量有限,屬性數(shù)量也有限,導(dǎo)出的代碼冗余。當(dāng)時(shí)問了幾個(gè)高手,大家建議不要使用設(shè)計(jì)器而應(yīng)該自己手寫xml代碼。起初手寫時(shí)感覺特別麻煩,可是用幾天后你會(huì)發(fā)現(xiàn)手寫要比使用設(shè)計(jì)器好得多:你可以更加了解duilib,熟悉每個(gè)控件的各個(gè)屬性,對(duì)控件的控制也更加方便。而如果想稱心如意的脫離設(shè)計(jì)器去編寫xml文件,有非常有必要弄明白各個(gè)布局的用法和布局技巧。我現(xiàn)在可以完全靠手寫xml來做出一個(gè)程序的界面,相信用了一段duilib的朋友也是這樣。
在這里提醒一下新手朋友,在duilib的根目錄有一個(gè)屬性列表.xml的文件,他包含了絕大多數(shù)控件的絕大多數(shù)屬性的介紹,有不懂的屬性記得時(shí)常翻看他,同時(shí)不得不說這個(gè)文件包含的屬性的確是不全面的,想要知道最全面的屬性信息,可以看每個(gè)控件的源代碼,在SetAttribute函數(shù)中可以看到最全面的屬性信息!
要想手寫xml,當(dāng)然必須有一個(gè)編寫工具,原則上只要是可以編寫文本的工具都可以,大家根據(jù)習(xí)慣自己挑選適合的工具,我目前在使用的是sublime這款工具,感覺編寫xml非常方便,使用界面也不錯(cuò)。
6大布局的作用:
duilib的Layout目錄專門放置布局相關(guān)的容器控件,這6個(gè)布局分別為:Container、VerticalLayout、HorizaontalLayout、TileLayout、TabLayout、ChildLayout。容器之間可以任意相互嵌套,我分別說明他們的用法。
首先我要說明一下,下面介紹的時(shí)候,我都默認(rèn)認(rèn)為每個(gè)控件的float屬性為false,也就是不使用絕對(duì)定位,這個(gè)屬性會(huì)打破各個(gè)布局的作用。
Container:
Container布局是其他所有布局以及含有容器特性(如CList、CListContainerElement)的控件的基類,而實(shí)際上開發(fā)過程中很少使用這個(gè)布局,只用他來做其他更高級(jí)的布局的基類。因?yàn)镃ontainer布局中的所有控件都會(huì)自動(dòng)填充滿整個(gè)布局,所有的控件都疊到了一起,假如恰好有什么需求要讓子控件都覆蓋起來,而且可以隨著容器的改變而自適應(yīng)填充的話,Container就是不二之選。而除了這個(gè)效果之外,一般我們不使用它。
VerticalLayout、HorizaontalLayout:
VerticalLayout與HorizaontalLayout布局無疑是duilib中最常使用的兩個(gè)布局,巧妙的使用這兩個(gè)布局可以滿足大多數(shù)的布局需求。從單詞的意思上不難看出VerticalLayout是縱向布局,HorizaontalLayout是橫向布局。這門兩個(gè)直接繼承自Container布局。
VerticalLayout布局會(huì)讓他包含的元素都縱向排列開,HorizaontalLayout布局會(huì)讓給他包含的元素都橫向排列開:如圖
我故意沒讓控件填滿整個(gè)容器,為了說明這兩個(gè)布局不會(huì)強(qiáng)行讓子元素的總和去填滿容器,縱向布局會(huì)從上到下根據(jù)每個(gè)控件的高度讓他們排到一起,橫向布局會(huì)從左到右根據(jù)每個(gè)控件的寬度讓他們排到一起。另外可以看到,縱向布局只關(guān)心子元素的高度,而不會(huì)強(qiáng)行讓子元素的寬度等于容器的寬度,這點(diǎn)從圖片可以看到,橫向布局同理也是只關(guān)心子元素的寬度。而這兩個(gè)布局經(jīng)常會(huì)嵌套使用,如下效果:
可以看到我最外層使用了一個(gè)縱向布局,他包含了橫縱橫三個(gè)布局(分別為紅綠藍(lán)顏色),每個(gè)橫向布局里又分別包含了幾個(gè)按鈕。我們在編寫界面時(shí)經(jīng)常用到這個(gè)方法!以下是這個(gè)布局效果圖對(duì)應(yīng)的xml代碼:
[html] view plain copy%20 %20 %20 TileLayout:
%20 %20 %20 TileLayout布局是用來做類似360工具箱的效果:
在前面的文章里,我寫的《duilib中ListCtrl控件的實(shí)現(xiàn)》和《仿酷狗音樂播放器開發(fā)日志十三——左側(cè)功能塊的完善》正是使用了這個(gè)布局完成的。這個(gè)布局有有兩個(gè)關(guān)鍵屬性:
[html] view plain copy
%20 %20 %20columns和itemsize屬性,這兩個(gè)屬性不能一起用,應(yīng)該只是用其中的一個(gè)。使用columns屬性可以來設(shè)置每行中包含的列數(shù),他會(huì)自動(dòng)把包含的元素從左到右從上到下按照columns屬性的設(shè)置排列起來,他把每行的列數(shù)固定死了。而itemsize有兩個(gè)字段,通過我讀
但是在duilib中TabLayout只是下面的布局界面,而不包含頂端的選項(xiàng)卡按鈕,所以經(jīng)常用Option控件配合他一起使用,使用他時(shí)他會(huì)把他包含的下一級(jí)元素作為一個(gè)頁面,所以我們通常在他里面放入橫縱向布局來作為一個(gè)頁面,在橫縱向布局里再規(guī)劃每個(gè)頁面的外觀。
這個(gè)控件的詳細(xì)使用方法大家可以看duilib自帶的360demo,我就不贅述了!
ChildLayout:
ChildLayout布局比較少用,因?yàn)樗墓δ芸梢杂闷渌季謥泶妫淖饔镁褪菑囊粋€(gè)xml文件中加載布局來嵌入到ChildLayout布局所在的地方,使用這個(gè)布局一般只需要指定xmlfile屬性來設(shè)置xml文件位置就可以了。他的意義在于可以把繁雜的大量xml代碼分隔開。比如他和TabLayout布局結(jié)合,讓TabLayout布局包含5個(gè)ChildLayout布局,而每個(gè)ChildLayout布局分別從5個(gè)xml文件加載自己的布局文件,這樣就可以分塊化的編寫布局代碼。
實(shí)際上有個(gè)比他更好用的標(biāo)簽,就是Include標(biāo)簽,Include不屬于布局,但他的作用在布局方面非常類似ChildLayout,指定他的Source屬性到某個(gè)xml文件就可以了。相對(duì)ChildLayout,Include的優(yōu)點(diǎn)是可以自動(dòng)識(shí)別自定義控件,而ChildLayout不可以!
在這里要提一下360Demo的自定義控件,這個(gè)demo的自定義控件做法誤導(dǎo)了很多人,里面使用了自定義控件的方法,把一個(gè)xml布局文件嵌入到界面里,這種做法完全沒必要,直接使用Include標(biāo)簽,一句xml代碼可以完全代替自定義控件。
這里給出一個(gè)Include的用法:
[html] view plain copy%20 %20 %20其中source屬性指定xml文件的路徑,count指定解析的次數(shù)。
絕對(duì)布局的意義與用法:
%20 %20 %20 在知道了6大布局的用法之后,知道了各種樣式的界面外觀的大致布局方法,而這還遠(yuǎn)不夠讓我們寫出漂亮的布局外觀,只有配合相對(duì)布局與絕對(duì)布局才可以更好的控制界面的元素。值得一提的是,我這里說的相對(duì)布局和絕對(duì)布局并不是一個(gè)容器或者控件,這只是一種技巧和使用方法,用在容器布局所包含的控件上,常用到橫縱向布局中。
%20 %20 %20我先來介紹絕對(duì)布局,笼統(tǒng)上說絕對(duì)布局和相對(duì)布局其實(shí)只有一個(gè)差別,也就是我在前面提到的float屬性,容器中包含的控件float屬性為真就是絕對(duì)布局,為假就是相對(duì)布局。不要小看這一個(gè)屬性,他帶來的效果可以天壤之別!
%20 %20 %20給控件的float屬性設(shè)為真后,就使用了絕對(duì)布局,故名意思,絕對(duì)布局就是讓控件的坐標(biāo)絕對(duì)化,這樣這個(gè)控件就不受他的容器的束縛而可以自己隨意設(shè)置自己的位置!比如在橫縱向布局中給他們包含的子控件設(shè)置float屬性,這個(gè)控件就不會(huì)被自動(dòng)橫縱向排列。而我的建議是,能不用絕對(duì)布局就別用絕對(duì)布局!原因有三個(gè):
%20 %20 %201)絕對(duì)布局破壞了各個(gè)容器的特性,而不受容器的束縛。
%20 %20 %202)絕對(duì)布局讓控件的坐標(biāo)固定,不利于控件自動(dòng)調(diào)節(jié)位置。
%20 %20 %203)后面提到的相對(duì)布局幾乎可以完成絕對(duì)布局的所有特性。
%20 %20 那么為什么要用絕對(duì)布局,因?yàn)樗囊粋€(gè)功能是相對(duì)布局無法完成的,就是讓控件或者布局重疊或者相交!有的時(shí)候我們必須這樣做來讓控件組合起來達(dá)到一些效果。我可以明確的說,我在做仿酷狗播放器的過程中,整個(gè)xml布局代碼只用了2個(gè)絕對(duì)布局,一個(gè)是編寫搜索欄《仿酷狗音樂播放器開發(fā)日志二——搜索欄的編寫》,一個(gè)是編寫電臺(tái)控件。如圖:
另外一個(gè)非常經(jīng)典的使用絕對(duì)布局的例子就是我前幾天寫的《用duilib制作仿QQ2013動(dòng)態(tài)背景登錄器》,這些例子都是因?yàn)橐尶丶丿B起來組合出新的控件才使用了絕對(duì)布局,如果不讓控件重疊或者沒有特殊需求,最好別用絕對(duì)布局。
雖然不建議使用,但我也得說一下絕對(duì)布局相關(guān)的屬性和使用技巧。
1)把float屬性設(shè)置為真。
2)設(shè)置pos屬性,這個(gè)屬性在float為真時(shí)才有效,他包含四個(gè)字段,分別以為了控件的左上右下下個(gè)坐標(biāo)的位置,但是建議只指定前兩個(gè)字段來設(shè)置控件的左上角的坐標(biāo),控件的寬度用width和height屬性來控制,這樣做的好處是避免了計(jì)算右下角坐標(biāo)的繁瑣!以后修改的時(shí)候也很清晰!
舉出一個(gè)例子:
[html] view plain copy%20 %20 %20 %20用了這個(gè)屬性,就可以讓控件擁有相對(duì)布局的一部分特性,那就是根據(jù)容器的大小,自己可以調(diào)整位置和大小!這個(gè)特點(diǎn)我在《仿酷狗音樂播放器開發(fā)日志二——搜索欄的編寫》用到了,是為了讓搜索按鈕可以自己移動(dòng)。這個(gè)屬性的前兩個(gè)字段表示橫縱向的位移值,后兩個(gè)字段表示縮放值,具體效果大家應(yīng)該自己實(shí)踐一下!另外這個(gè)屬性默認(rèn)是有嚴(yán)重bug的,就是窗體最小化再恢復(fù)后有這個(gè)屬性的控件會(huì)自動(dòng)無規(guī)律偏移,這個(gè)bug我修復(fù)了,詳見《仿酷狗音樂播放器開發(fā)日志二——搜索欄的編寫》。
%20 %20 %20 %20這樣就介紹完了絕對(duì)布局,然后就是整片文章的最重要部分,相對(duì)布局!
相對(duì)布局的意義與用法:
%20 %20 %20 我把相對(duì)布局的介紹放到最后,因?yàn)樗苤匾?/p>
%20 %20 %20 在容器內(nèi)部使用控件或者容器時(shí),float屬性設(shè)置為flase(duilib默認(rèn)為false)就是相對(duì)布局了。這是我非常推薦使用的,前面我也說了我在寫仿酷狗的整個(gè)布局中,上百個(gè)控件中我只給兩個(gè)控件使用了絕對(duì)布局,其余都是相對(duì)布局。他的優(yōu)點(diǎn)如下:
%20 %20 %20 %201)布局和控件是可以根據(jù)窗體的大小改變而自動(dòng)調(diào)整位置的,這點(diǎn)很重要
%20 %20 %20 %202)不需要絕對(duì)布局那樣麻煩的計(jì)算各個(gè)控件的位置
%20 %20 %20 %203)在容器中調(diào)整前一個(gè)控件的位置,后面的控件都會(huì)自動(dòng)調(diào)整坐標(biāo)
%20 %20 %20其實(shí)總得來說使用相對(duì)布局意義就是使用布局控件的自動(dòng)排列特性!
%20 %20 %20使用了相對(duì)布局后,就不用設(shè)置float屬性和pos屬性,一般只設(shè)置甚至不設(shè)置width和height屬性。這點(diǎn)很重要,如果你的控件或者布局的大小是固定的,那么就設(shè)置width和height屬性,如果想讓控件或者布局根據(jù)窗體的大小而自動(dòng)調(diào)整大小和位置,就不設(shè)置這兩個(gè)屬性。如果只設(shè)置了一個(gè)屬性,比如width設(shè)置為100,而height不設(shè)置,那么他的高度是自動(dòng)調(diào)整的而寬度是固定的。父容器會(huì)自動(dòng)安排他包含的元素,讓含有width和height屬性的控件占據(jù)相應(yīng)的大小,把剩下的空間都分配給沒有設(shè)置wieth和height屬性的容器或者控件里。看下面一個(gè)例子:
[html] view%20plain copy%20
%20 %20 %20可以看到窗體的大小為300x300,而最外層的是一個(gè)名為Fahter的縱向容器,包含三個(gè)子容器。而Father沒有指定width和height,所以當(dāng)我改變了窗體的大小時(shí),F(xiàn)ather會(huì)自動(dòng)調(diào)整自己的大小到和窗體大小相同,而三個(gè)子容器我都眉頭指定width屬性,所以三個(gè)子容器的寬度和Father是一樣,也就是他們的寬度都是和窗體寬度一樣,并且會(huì)自動(dòng)調(diào)整。Sub1和Sub3的高度設(shè)置為50,所以他們的高度就固定了,而Sbu2的高度也沒有指定,那他會(huì)自動(dòng)占據(jù)了除了Sub1和Sub2的所有空間!其實(shí)這個(gè)例子的布局是非常常見的界面布局例子,比如說酷狗,sub1和sub3分別表示標(biāo)題欄和狀態(tài)欄,sub2為程序的主界面:
關(guān)于酷狗的更加詳細(xì)的布局分析可以看我前面寫的博客《仿酷狗音樂播放器開發(fā)日志——整體框架分析》,幾乎每開發(fā)酷狗的一部分,我都會(huì)把布局分析一下寫出來。
把這些知識(shí)綜合起來,現(xiàn)在就可以寫出一個(gè)自動(dòng)調(diào)整大小的大致布局了,但是還沒法精確控制每個(gè)控件的位置。
利用上面介紹的自動(dòng)占位的特性,我這里舉一個(gè)標(biāo)題欄編寫的例子:
[html] view plain copy這個(gè)例子是我的仿酷狗播放器的換膚窗體的標(biāo)題欄。他的外層是一個(gè)橫向布局,高度為30,寬度隨窗體調(diào)整。讓標(biāo)題文字居于左側(cè),關(guān)閉按鈕在最右側(cè),如果讓窗體調(diào)整寬度后文字和關(guān)閉按鈕自動(dòng)調(diào)整位置,就需要把中間的空位占滿。這時(shí)我們就需要一個(gè)占位控件,不給他設(shè)置width和height屬性,這樣子他就會(huì)自動(dòng)占據(jù)剩余的空間!就達(dá)到了相對(duì)布局的自動(dòng)調(diào)整位置的效果。這個(gè)使用方法是相對(duì)布局里非常常用的!而這個(gè)占位控件在沒有什么其他要求時(shí)建議像我給出的例子那樣,使用Control控件,因?yàn)樗撬锌丶腿萜鞯淖嫦然悾a和屬性相對(duì)是最少的,這樣有利于提高程序的效率!
在充分理解了占位的技巧后,再配合一些微調(diào)屬性,就可以完美控制各個(gè)控件了,這幾個(gè)微調(diào)屬性分別是inset、padding、childpadding,這幾個(gè)屬性的介紹如下:
[html] view plain copy%20 %20 %20inset屬性
%20 %20 %20這是給容器控件使用的,使用后他所包含的所有使用相對(duì)布局的元素,都會(huì)被限制在設(shè)置的范圍內(nèi),適合對(duì)容器內(nèi)所用元素進(jìn)行整體的坐標(biāo)控制。比如在前面提到的做360工具箱時(shí),我們使用TileLayout容器來存放每一個(gè)工具,我們首先設(shè)置inset屬性,就可以讓所有的工具項(xiàng)限制在一定范圍內(nèi),例子如下:
[html] view%20plain copy通過設(shè)置inset屬性,讓所有元素限制在一定范圍內(nèi)而不用重復(fù)設(shè)置每個(gè)元素的屬性。
childpadding屬性:
childpadding屬性設(shè)置容器內(nèi)每個(gè)元素之間的間距,這個(gè)比較容易理解,上面的例子中也用到了childpadding屬性。這個(gè)屬性在不同容器中代表不同意思,在橫向布局中代表子控件之間的橫向間隔,在縱向布局中代表子控件之間的縱向間隔,在TileLayout容器中代碼行與行之間的間隔!
padding屬性:
padding屬性是相對(duì)布局中最常用的屬性!用來設(shè)置相對(duì)于前一個(gè)控件的位置,這個(gè)屬性的控件位置微調(diào)的關(guān)鍵。一般只用他的前兩個(gè)字段,設(shè)置左邊距和上邊距,后兩個(gè)字段是無效的,或者說存在問題(為什么會(huì)有問題?請看源碼)。不過使用這兩個(gè)字段就夠了。這是我的仿酷狗播放器的狀態(tài)的布局代碼:
[html] view plain copy使用padding屬性,這是底部這四個(gè)按鈕的相對(duì)位置。如果我想整體讓這四個(gè)控件向右位移10像素,那么我只要設(shè)置第一個(gè)按鈕的padding屬性為padding="10,0,0,0",就可以了,其他布局完全不需要修改!
結(jié)束語
說到這里也就把布局的知識(shí)總結(jié)得差不多了,對(duì)于duilib的新手朋友,建議多看看各個(gè)demo的布局文件,他們幾乎涵蓋了所有知識(shí)點(diǎn)。然后結(jié)合我總結(jié)的東西自己手動(dòng)寫幾個(gè)布局代碼,相信很快就可以熟練編寫界面布局了。另外我的前面博客里經(jīng)常會(huì)分析布局,大家也可以看看。
我使用duilib的時(shí)間也不算長,水平有限,文章中有什么錯(cuò)誤或者描述不清,請留言給我,我會(huì)及時(shí)糾正!
Redrain 2014.8.13
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注