duilib各种布局的作用,相对布局与绝对布局的的意义与用法
duilib各種布局的作用,相對布局與絕對布局的的意義與用法?????????????????????
原文? http://blog.csdn.net/zhuhongshu/article/details/38531447 主題 Duilib轉載請說明原出處,謝謝~~
? ? ? ?我使用duilib快3個月了,總體感覺duilib的使用還是較為簡單的,只是剛入門時可能有些摸不清頭腦。今天寫一篇關于duilib的入門日志,大致說一下duilib中的各個布局的作用,以及很關鍵的相對布局與絕對布局的意義與用法。希望可以幫到使用duilib的新手朋友們。duilib高手就可以直接省略這篇文章了!
? ? ? 我剛使用duilib的時候非常依賴duilib自帶的設計器,用他可以拖拉控件,可視化的做出自己想要的界面。可是用一段時間就會發現原帶的設計器有很多bug,時不時會崩潰,支持的控件數量有限,屬性數量也有限,導出的代碼冗余。當時問了幾個高手,大家建議不要使用設計器而應該自己手寫xml代碼。起初手寫時感覺特別麻煩,可是用幾天后你會發現手寫要比使用設計器好得多:你可以更加了解duilib,熟悉每個控件的各個屬性,對控件的控制也更加方便。而如果想稱心如意的脫離設計器去編寫xml文件,有非常有必要弄明白各個布局的用法和布局技巧。我現在可以完全靠手寫xml來做出一個程序的界面,相信用了一段duilib的朋友也是這樣。
? ? ?在這里提醒一下新手朋友,在duilib的根目錄有一個屬性列表.xml的文件,他包含了絕大多數控件的絕大多數屬性的介紹,有不懂的屬性記得時常翻看他,同時不得不說這個文件包含的屬性的確是不全面的,想要知道最全面的屬性信息,可以看每個控件的源代碼,在SetAttribute函數中可以看到最全面的屬性信息!
? ? ? 要想手寫xml,當然必須有一個編寫工具,原則上只要是可以編寫文本的工具都可以,大家根據習慣自己挑選適合的工具,我目前在使用的是sublime這款工具,感覺編寫xml非常方便,使用界面也不錯。
6大布局的作用:
? ? ? duilib的Layout目錄專門放置布局相關的容器控件,這6個布局分別為:Container、VerticalLayout、HorizaontalLayout、TileLayout、TabLayout、ChildLayout。容器之間可以任意相互嵌套,我分別說明他們的用法。
? ? ? 首先我要說明一下,下面介紹的時候,我都默認認為每個控件的float屬性為false,也就是不使用絕對定位,這個屬性會打破各個布局的作用。
? ? Container:
? ? ?Container布局是其他所有布局以及含有容器特性(如CList、CListContainerElement)的控件的基類,而實際上開發過程中很少使用這個布局,只用他來做其他更高級的布局的基類。因為Container布局中的所有控件都會自動填充滿整個布局,所有的控件都疊到了一起。而這個效果一般不是我們想要的。我目前想得到的他的唯一用途就是用于絕對布局,而且里面的所有元素都使用絕對布局。絕對布局的概念看下文。
? ? ? VerticalLayout、HorizaontalLayout:
? ? ? VerticalLayout與HorizaontalLayout布局無疑是duilib中最常使用的兩個布局,巧妙的使用這兩個布局可以滿足大多數的布局需求。從單詞的意思上不難看出 VerticalLayout是縱向布局,HorizaontalLayout是橫向布局。這門兩個直接繼承自Container布局。
? ? ? VerticalLayout布局會讓他包含的元素都縱向排列開, HorizaontalLayout布局會讓給他包含的元素都橫向排列開:如圖
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? 我故意沒讓控件填滿整個容器,為了說明這兩個布局不會強行讓子元素的總和去填滿容器,縱向布局會從上到下根據每個控件的高度讓他們排到一起,橫向布局會從左到右根據每個控件的寬度讓他們排到一起。另外可以看到,縱向布局只關心子元素的高度,而不會強行讓子元素的寬度等于容器的寬度,這點從圖片可以看到,橫向布局同理也是只關心子元素的寬度。而這兩個布局經常會嵌套使用,如下效果:
? ? ? ?可以看到我最外層使用了一個縱向布局,他包含了橫縱橫三個布局(分別為紅綠藍顏色),每個橫向布局里又分別包含了幾個按鈕。我們在編寫界面時經常用到這個方法!以下是這個布局效果圖對應的xml代碼:
xml version="1.0" encoding="utf-8" standalone="yes" <Window size="300,226"><VerticalLayout width="300" height="318" bkcolor="#FFFFFFFF"><HorizontalLayout width="300" height="65" bkcolor="#FFFF0000"><Button text="按鈕測試" width="60" height="35" /><Button text="按鈕測試" width="60" height="63" /><Button text="按鈕測試" width="60" height="35" /></HorizontalLayout><VerticalLayout width="300" height="96" bkcolor="#FF00FF00"><Button text="按鈕測試" width="60" height="64" /><Button text="按鈕測試" width="60" height="75" /><Button text="按鈕測試" width="60" height="64" /><Button text="按鈕測試" width="60" height="64" /></VerticalLayout><HorizontalLayout width="300" height="65" bkcolor="#FF0000FF"><Button text="按鈕測試" width="60" height="47" /><Button text="按鈕測試" width="60" height="64" /><Button text="按鈕測試" width="60" height="64" /></HorizontalLayout></VerticalLayout> </Window>? ? ? ?TileLayout:
? ? ? ? TileLayout布局是用來做類似360工具箱的效果:
? ? ? ?在前面的文章里,我寫的《 duilib中ListCtrl控件的實現 》 和 《 仿酷狗音樂播放器開發日志十三——左側功能塊的完善 》 正是使用了這個布局完成的,這個布局有一個columns屬性來設置每行中包含的列數,他會自動把包含的元素從左到右從上到下按照 columns屬性的設置排列起來,讓我們做出工具箱的效果。
? ? ?TabLayout:
? ? ?TabLayout布局同樣常用,他就像MFC的選項卡 CTabCtrl
控件,如圖:
? ? ? 但是在duilib中TabLayout只是下面的布局界面,而不包含頂端的選項卡按鈕,所以經常用Option控件配合他一起使用,使用他時他會把他包含的下一級元素作為一個頁面,所以我們通常在他里面放入橫縱向布局來作為一個頁面,在橫縱向布局里再規劃每個頁面的外觀。
? ? ? 這個控件的詳細使用方法大家可以看duilib自帶的360demo,我就不贅述了!
? ? ? ChildLayout:
? ? ? ChildLayout布局比較少用,因為他的功能可以用其他布局來代替,他的作用就是從一個xml文件中加載布局來嵌入到ChildLayout布局所在的地方,使用這個布局一般只需要指定xmlfile屬性來設置xml文件位置就可以了。他的意義在于可以把繁雜的大量xml代碼分隔開。比如他和TabLayout布局結合,讓TabLayout布局包含5個ChildLayout布局,而每個ChildLayout布局分別從5個xml文件加載自己的布局文件,這樣就可以分塊化的編寫布局代碼。
絕對布局的意義與用法:
? ? ? ?在知道了6大布局的用法之后,知道了各種樣式的界面外觀的大致布局方法,而這還遠不夠讓我們寫出漂亮的布局外觀,只有配合相對布局與絕對布局才可以更好的控制界面的元素。值得一提的是,我這里說的相對布局和絕對布局并不是一個容器或者控件,這只是一種技巧和使用方法,用在容器布局所包含的控件上,常用到橫縱向布局中。
? ? ? 我先來介紹絕對布局,籠統上說絕對布局和相對布局其實只有一個差別,也就是我在前面提到的float屬性,容器中包含的控件float屬性為真就是絕對布局,為假就是相對布局。不要小看這一個屬性,他帶來的效果可以天壤之別!
? ? ? 給控件的float屬性設為真后,就使用了絕對布局,故名意思,絕對布局就是讓控件的坐標絕對化,這樣這個控件就不受他的容器的束縛而可以自己隨意設置自己的位置!比如在橫縱向布局中給他們包含的子控件設置float屬性,這個控件就不會被自動橫縱向排列。而我的建議是,能不用絕對布局就別用絕對布局!原因有三個:
? ? ? 1)絕對布局破壞了各個容器的特性,而不受容器的束縛。
? ? ? 2)絕對布局讓控件的坐標固定,不利于控件自動調節位置。
? ? ? 3)后面提到的相對布局幾乎可以完成絕對布局的所有特性。
? ? ?那么為什么要用絕對布局,因為他的一個功能是相對布局無法完成的,就是讓控件或者布局重疊或者相交!有的時候我們必須這樣做來讓控件組合起來達到一些效果。我可以明確的說,我在做仿酷狗播放器的過程中,整個xml布局代碼只用了2個絕對布局,一個是編寫搜索欄 《 仿酷狗音樂播放器開發日志二——搜索欄的編寫 》 ,一個是編寫電臺控件。如圖:
? ? ? ? 另外一個非常經典的使用絕對布局的例子就是我前幾天寫的 《 用duilib制作仿QQ2013動態背景登錄器 》 ,這些例子都是因為要讓控件重疊起來組合出新的控件才使用了絕對布局,如果不讓控件重疊或者沒有特殊需求,最好別用絕對布局。
? ? ? ? 雖然不建議使用,但我也得說一下絕對布局相關的屬性和使用技巧。
? ? ? ? 1)把float屬性設置為真。
? ? ? ? 2)設置pos屬性,這個屬性在float為真時才有效,他包含四個字段,分別以為了控件的左上右下下個坐標的位置,但是建議只指定前兩個字段來設置控件的左上角的坐標,控件的寬度用width和height屬性來控制,這樣做的好處是避免了計算右下角坐標的繁瑣!以后修改的時候也很清晰!
? ? ? ? 舉出一個例子:
<Label name="MusicName" float="true" pos="100,100" width="26" height="22" textcolor="#FF505050" endellipsis="true" /> ? ? ? ? 這里設置了一個Label控件,左上角放到100,100的坐標上,控件高22,寬26? ? ? ? 不得不提一個很有用的屬性,那就是relativepos屬性,屬性列表沒有列出這個屬性,這是我自己總結的
<Attribute name="relativepos" default="0,0,0,0" type="RECT" comment="設置相對移動,float為真時,分別表示橫縱向位移值,橫縱向縮放值,移動單位建議50或100"/> ? ? ? ? 用了這個屬性,就可以讓控件擁有相對布局的一部分特性,那就是根據容器的大小,自己可以調整位置和大小!這個特點我在 《 仿酷狗音樂播放器開發日志二——搜索欄的編寫 》 用到了,是為了讓搜索按鈕可以自己移動。這個屬性的前兩個字段表示橫縱向的位移值,后兩個字段表示縮放值,具體效果大家應該自己實踐一下!另外這個屬性默認是有嚴重bug的,就是窗體最小化再恢復后有這個屬性的控件會自動無規律偏移,這個bug我修復了,詳見 《 仿酷狗音樂播放器開發日志二——搜索欄的編寫 》 。? ? ? ? 這樣就介紹完了絕對布局,然后就是整片文章的最重要部分,相對布局!
相對布局的意義與用法:
? ? ? ?我把相對布局的介紹放到最后,因為它很重要!
? ? ? ?在容器內部使用控件或者容器時,float屬性設置為flase(duilib默認為false)就是相對布局了。這是我非常推薦使用的,前面我也說了我在寫仿酷狗的整個布局中,上百個控件中我只給兩個控件使用了絕對布局,其余都是相對布局。他的優點如下:
? ? ? ? 1)布局和控件是可以根據窗體的大小改變而自動調整位置的,這點很重要
? ? ? ? 2)不需要絕對布局那樣麻煩的計算各個控件的位置
? ? ? ? 3)在容器中調整前一個控件的位置,后面的控件都會自動調整坐標
? ? ? 其實總得來說使用相對布局意義就是使用布局控件的自動排列特性!
? ? ? 使用了相對布局后,就不用設置float屬性和pos屬性,一般只設置甚至不設置width和height屬性。這點很重要,如果你的控件或者布局的大小是固定的,那么就設置width和height屬性,如果想讓控件或者布局根據窗體的大小而自動調整大小和位置,就不設置這兩個屬性。如果只設置了一個屬性,比如width設置為100,而height不設置,那么他的高度是自動調整的而寬度是固定的。父容器會自動安排他包含的元素,讓含有width和height屬性的控件占據相應的大小,把剩下的空間都分配給沒有設置wieth和height屬性的容器或者控件里。看下面一個例子:
xml version="1.0" encoding="utf-8" standalone="yes" <Window size="300,300"><VerticalLayout name="Father"><HorizontalLayout name="Sub1" height="50" ></HorizontalLayout><VerticalLayout name="Sub2"></VerticalLayout><HorizontalLayout name="Sub3" height="50" ></HorizontalLayout></VerticalLayout> </Window> ? ? ? ? 可以看到窗體的大小為300x300,而最外層的是一個名為Fahter的縱向容器,包含三個子容器。而Father沒有指定width和height,所以當我改變了窗體的大小時,Father會自動調整自己的大小到和窗體大小相同,而三個子容器我都眉頭指定width屬性,所以三個子容器的寬度和Father是一樣,也就是他們的寬度都是和窗體寬度一樣,并且會自動調整。Sub1和Sub3的高度設置為50,所以他們的高度就固定了,而Sbu2的高度也沒有指定,那他會自動占據了除了Sub1和Sub2的所有空間!其實這個例子的布局是非常常見的界面布局例子,比如說酷狗,sub1和sub3分別表示標題欄和狀態欄,sub2為程序的主界面:
? ? ? ?關于酷狗的更加詳細的布局分析可以看我前面寫的博客 《 仿酷狗音樂播放器開發日志——整體框架分析 》 ,幾乎每開發酷狗的一部分,我都會把布局分析一下寫出來。
? ? ? 把這些知識綜合起來,現在就可以寫出一個自動調整大小的大致布局了,但是還沒法精確控制每個控件的位置。
? ? ? 利用上面介紹的自動占位的特性,我這里舉一個標題欄編寫的例子:
<HorizontalLayout name="background" height="30" bkimage="file='UI\BKImage\4.jpg' source='0,0,1000,30'" ><!-- 標題欄 --><Label text="皮膚與窗口調整——Redrain播放器" textcolor="#FFFFFFFF" textpadding="5,0,0,0" font="1" autocalcwidth="false" width="300"/><Control /><Button name="closebtn" width="23" height="18" padding="0,6,0,0" normalimage="UI\title\close_normal.png" hotimage="UI\title\close_hover.png" pushedimage="UI\title\close_down.png" /> </HorizontalLayout>? ? ? ?這個例子是我的仿酷狗播放器的換膚窗體的標題欄。他的外層是一個橫向布局,高度為30,寬度隨窗體調整。讓標題文字居于左側,關閉按鈕在最右側,如果讓窗體調整寬度后文字和關閉按鈕自動調整位置,就需要把中間的空位占滿。這時我們就需要一個占位控件,不給他設置width和height屬性,這樣子他就會自動占據剩余的空間!就達到了相對布局的自動調整位置的效果。這個使用方法是相對布局里非常常用的!而這個占位控件在沒有什么其他要求時建議像我給出的例子那樣,使用Control控件,因為他是所有控件和容器的祖先基類,代碼和屬性相對是最少的,這樣有利于提高程序的效率!
? ? ? ?在充分理解了占位的技巧后,再配合一些微調屬性,就可以完美控制各個控件了,這幾個微調屬性分別是 inset、padding、childpadding ,這幾個屬性的介紹如下:
<Attribute name="padding" default="0,0,0,0" type="RECT" comment="外邊距,如(2,2,2,2)"/> <Attribute name="inset" default="0,0,0,0" type="RECT" comment="容器的內邊距,如(2,2,2,2)"/> <Attribute name="childpadding" default="0" type="DWORD" comment="子控件之間的額外距離,如(4)"/> ? ? ? 在float為假,也就是相對布局中,這幾個屬性才起效。? ? ? inset屬性
? ? ? 這是給容器控件使用的,使用后他所包含的所有使用相對布局的元素,都會被限制在設置的范圍內,適合對容器內所用元素進行整體的坐標控制。比如在前面提到的做360工具箱時,我們使用TileLayout容器來存放每一個工具,我們首先設置inset屬性,就可以讓所有的工具項限制在一定范圍內,例子如下:
<TileLayout name="listctrl" width="540" height="400" inset="20,20,0,20" childpadding="20,40,20,40" vscrollbar="true" columns="2" bkimage="CustomList\List_bk.png" itemhotimage="CustomList\ListItem_bk_hover.png" itemselectedimage="CustomList\ListItem_bk_hover.png"> </TileLayout>? ? ? ?通過設置inset屬性,讓所有元素限制在一定范圍內而不用重復設置每個元素的屬性。
? ? ? childpadding屬性:
? ? ? childpadding屬性設置容器內每個元素之間的間距,這個比較容易理解,上面的例子中也用到了childpadding屬性。四個字段分別是代表左上右下的間距。
? ? ?? padding屬性:
? ? ? padding屬性是相對布局中最常用的屬性!用來設置相對于前一個控件的位置,這個屬性的控件位置微調的關鍵。一般只用他的前兩個字段,設置左邊距和上邊距,后兩個字段是無效的,或者說存在問題(為什么會有問題?請看源碼)。不過使用這兩個字段就夠了。這是我的仿酷狗播放器的狀態的布局代碼:
<HorizontalLayout height="30" inset="77,0,0,0" bkimage="UI\statusbar\status_bk.png"><!-- 狀態欄 --><Button width="31" height="30" padding="0,0,0,0" normalimage="UI\statusbar\add_normal.png" hotimage="UI\statusbar\add_hover.png" pushedimage="UI\statusbar\add_down.png" /><Button width="31" height="30" padding="40,0,0,0" normalimage="UI\statusbar\locate_normal.png" hotimage="UI\statusbar\locate_hover.png" pushedimage="UI\statusbar\locate_down.png" /><Button width="31" height="30" padding="40,0,0,0" normalimage="UI\statusbar\search_normal.png" hotimage="UI\statusbar\search_hover.png" pushedimage="UI\statusbar\search_down.png" /><Button width="31" height="30" padding="40,0,0,0" normalimage="UI\statusbar\setting_normal.png" hotimage="UI\statusbar\setting_hover.png" pushedimage="UI\statusbar\setting_down.png" /><Control /><Label text="Redrain仿酷狗音樂盒DirectUI ^_^" textpadding="0,6,0,0" width="30" font="0" /> </HorizontalLayout>? ? ? 使用padding屬性,這是底部這四個按鈕的相對位置。如果我想整體讓這四個控件向右位移10像素,那么我只要設置第一個按鈕的padding屬性為padding="10,0,0,0",就可以了,其他布局完全不需要修改!
結束語
? ? ? 說到這里也就把布局的知識總結得差不多了,對于duilib的新手朋友,建議多看看各個demo的布局文件,他們幾乎涵蓋了所有知識點。然后結合我總結的東西自己手動寫幾個布局代碼,相信很快就可以熟練編寫界面布局了。
總結
以上是生活随笔為你收集整理的duilib各种布局的作用,相对布局与绝对布局的的意义与用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 帧内16*16模式的宏块数据传输顺序
- 下一篇: wpf中:xaml中的命名空间的引入方法