自適應XAML布局經驗總結 (一)原則和頁面結構設計


XAML布局回顧

Grid和StackPanel是核心布局,尤其以Grid最為重要。

Grid是網格布局,XAML的設計者有可能參考了Html里的Table設計了Grid布局,但進行了改進。Html中的Table是tr套td,要想變動行列非常麻煩。XAML中的Grid使用的是指定行列序號和跨行跨列數的方式,修改起來靈活方便。

Grid里行或列的大小有三種方式,一種方式是固定大小(Double值),一種方式是由里面的內容決定(Auto),一種方式是按比例分割剩余空間(Double值加*,剩余空間由外部容器的大小決定)。

指定一個固定的Double值表示固定大小,它的單位默認為px(如果不寫單位),也可以是其他單位,見下。

px (默認值)為與設備無關的單位(每個單位 1/96 英寸)

in 表示英寸;1in==96px

cm 表示厘米;1cm==(96/2.54) px

pt 表示磅;1pt==(96/72) px

這里的px不是確定的像素值,而是一種與設備無關的單位,具體的解釋見后文。

指定為Auto指大小由最大的內容決定,由里面最大的內容把這個行或列撐開。

星的含義是按比例分割外界給它的剩余空間,*是1*的簡寫,把星前面的數加在一起做分母,每一個星前面的數做分子,作為這個行或列的比例。

還需結合最大值和最小值限制。

Grid.Row和Grid.Column指定在第幾行和第幾列,Grid.RowSpan和Grid.ColumnSpan指定跨幾行和跨幾列,行和列都是從0開始。

以上就是Grid布局的要點,其中的核心是分為了固定大小,內容決定和按比例分割剩余空間三種情況,這是自適應布局的基礎。

Android中的線性布局也支持固定大小,內容決定和按比例分割剩余空間三種情況,所以Android也可以並且應該制作自適應布局的界面。但線性布局一次只支持在一個方向上布局,如要實現復雜的網格效果,需要多層嵌套,比較麻煩。而Android中的Grid布局不能實現按比例分割剩余空間,只能支持部分自適應的情況。還有一種相對布局,實際界面設計時需要這幾種布局結合使用,使用技巧和XAML不同,但下文討論的自適應布局的原則對Android平台也是適用的。

StackPanel相當於Grid中全是Auto,但不需要指定序號,也省去了Grid定義部分分行或分列那塊。而且如果添加或移除中間部分的元素,不用改序號。所以在只需要按內容大小排列的時候使用StackPanel比Grid更簡潔方便。

Canvas就是絕對定位布局,通過指定X和Y坐標布局,待布局的元素應該有固定寬高。

Border是邊框,是裝飾,嚴格來講不能算布局,在里面只能放一個元素,它給加個邊,沒有Margin和Padding時對大小無影響。可以給布局容器套一層Border,給整個區域加個邊框。

ScrollViewer支持里面的內容滾動,里面的內容一般會超出容器大小,只顯示一部分,由滾動條控制滾動。

ViewBox對內容進行縮放,以適應容器大小。

WrapPanel是流式布局,一行一行的排,一行不夠折行到下一行。里面的東西固定寬高。

UniformGrid是固定行數或列數,內容一行一行或一列一列地排。

默認的Z方向上下關系是誰在后面,誰在上面。指定Panel.ZIndex可指定上下位置關系。

自適應動態布局

自適應動態布局是指界面的控件大小和位置會隨着控件中內容的變化和窗口大小的變化而自動調整,以達到較好的顯示效果的布局方案。

與之相對的是傳統的固定布局,固定布局不能隨內容和窗口大小變化,所以一般只支持固定窗口大小,顯示內容也不能隨意變化。

制作固定布局界面時一般直接指定控件的大小和位置。

要想制作自適應動態布局界面需要使用支持自適應動態布局的UI平台。基於XAML的平台就是這樣一個平台,Android平台也是,以前的Winform平台就不能完全支持自適應動態布局。

使用支持自適應動態布局的平台,也不是說就一定能制作出自適應動態布局的界面。如果還使用直接指定控件的大小和位置的方法,制作出的還是固定布局界面。

要想制作自適應動態布局界面,需要使用動態布局容器(Grid,StackPanel等)並遵循一定的原則。

自適應動態布局詳解

上文說自適應布局會隨着內容和窗口大小的變化自動調整控件大小和位置,下面來詳細分析一下。

變化的方面,即需要自適應的方面包括:

1. 窗口大小會變,對應全屏界面時就是顯示器分辨率會變化,就是說外層所給的布局總空間會變化。

2. 內容大小會變,包括文字多少會變,圖片大小會變,列表條目多少會變等情況。

3. 顯示屏DPI會變。

第一種情況我們用比例分割剩余空間(星)去應對,第二種情況我們用內容決定大小(Auto)去應對,第三種情況系統幫我們應對。下面詳細說說第三種情況。

上文提到WPF默認單位px不是像素,是與設備無關的單位,系統會處理這個單位和像素之間的關系,處理的依據是DPI。

Windows系統認為非高分辨率屏幕的DPI一般為96DPI左右,所以設備無關的單位和像素之間的比例為1比1。遇到高分辨率的屏幕(如Surface Pro 3),調節控制面板-外觀和個性化-顯示選項中的更改所有項目的大小選項,即更改系統DPI,見下圖,

Image(1)

更改系統DPI后WPF中設備無關的單位和像素之間的比例不再是1比1,而是1比多於1的值,也就是說系統會把界面等比例放大。這個DPI設置指的是桌面DPI,會影響所有的桌面程序。也就是說Windows希望用戶對桌面程序的顯示方式進行統一的設置。如果想顯示更多的內容就不要選擇放大,如果想顯示更大的內容就開啟放大。這種控制是全局的,用戶可以得到統一的用戶體驗。

但以前的桌面程序UI系統可能對這種放大機制的支持不是很好,需要應用程序自己控制。在WPF中放大機制能得到系統良好的支持,矢量的內容(文字,漸變畫刷,路徑等)不會有問題,但位圖的內容有問題。所以要盡量使用矢量的內容,位圖內容需額外處理。

Windows Store App使用的應該不是上述設置的桌面DPI,而是內部設置的DPI,但同樣也能得到良好的界面等比例放大支持。

Android系統也使用類似的機制來處理DPI變化的問題,界面也會根據DPI的變化進行等比例縮放,DPI為系統內部設置,和Windows Store App一樣不允許用戶修改(Root后可修改)。

總之,DPI的問題系統幫我們處理了,我們只考慮第一個和第二個方面的問題。所以可用空間變化和內容變化是核心問題。

下面對核心問題給出解決方案,即核心原則。

自適應動態布局核心原則

1. 有范圍,有最優。

有一個自適應的范圍,有一個最合適分辨率或窗口大小,不是無限適應。

比如,支持最小分辨率為1366*768的全屏程序,最合適分辨率為1920*1080,最大分辨率支持到2560*1440,長寬比可以變化,不一定為16:9。但小於最小分辨率可能造成顯示不全,大於最大分辨率可能造成顯示效果不好。在最合適分辨率時顯示效果最好,在支持的范圍內的顯示效果都可以接受。

2. 定DPI,定大小。

使用默認的96DPI進行設計,根據DPI進行放大的任務交給系統。所以一般不用添加動態調整字號的功能,使用一套固定的字號大小就可以了。我們假設大家都是使用默認DPI進行設計的,所以大家的大小標准是一致的。用戶想看小的不開系統放大選項,用戶想看大的就開系統放大選項,選擇權在用戶,而且各個程序的體驗是一致的。

高級的軟件,可在某些特定區域支持動態調整字號,比如Visual Studio的代碼編輯區。

3. 有定有變,比例分割填剩余

定的意思是區域大小是由內容決定的或手動指定一個固定大小。內容決定時,在內容不變的情況下,窗口大小變化了,該塊區域大小不變。區域大小不依賴於窗口大小而變化。相對窗口大小來說它是定的部分,由內容本身決定的。

手動指定固定大小也是定的情況,但使用內容決定優於使用固定大小,能不寫固定寬高就不寫固定寬高,由Margin和Padding加上內容來控制大小。一塊內容它的大小不應該是我給他強制指定一個大小,而應該是由它本身自己決定的,由內容(文字或圖片,文字指字的多少字體字號),Margin和Padding來決定這一塊區域的大小。如果指定了固定大小,內容(文字)變化了,就有可能存在多余空白或顯示不全。

變的意思是指區域大小會隨窗口大小變化而變化。由於窗口大小會發生變化,所以除去上述定的部分外的剩余空間會發生變化,剩余空間由變的部分來填充,而且可能會由多個變的部分按比例分割來填充。

變的部分有幾種情況,包括:

A. 自動縮放的情況。內容本身能自動縮放,圖片能自動縮放,但可能效果會不好,視頻可以自動縮放,ViewBox包起來的內容亦可以自動縮放。

B. 文本的情況。文本區域,如果這塊區域大小變了的話,顯示效果一般可以接受。文字少的話是一行,多了的話它會多折幾行,也可能會截斷,出...,或者出滾動條,也可不出滾動條用光標控制滾動,來通過滾動的方式顯示全部文本。

C. 可滾動區域。ListView,DataGrid等數據呈現區都屬於這種情況。

說到這里可以看出,其實自適應動態布局的核心問題是確定定的部分和變的部分。下面分享一下經驗。

標題,工具欄等一般為定的部分,表單的標簽部分也為定的部分。

空間大了的話由哪部分去撐,或者空間小了去擠哪部分,這種區域一般為變的部分。

展示用圖片,視頻,不定內容的文本塊,輸入內容的文本框,大量內容呈現的可滾動區域一般為變的部分。

自適應動態布局的優勢

固定布局和動態布局,固定布局固定大小和位置,動態布局使用布局系統進行布局。動態布局可以自適應窗口大小變化,如果沒有自適應窗口大小變化的需求,也應該使用動態布局,因為設計有可能會變,固定布局沒有可維護性。

動態布局是符合設計師的思路的。固定布局相當於把設計思路給柵格化了,柵格化的過程應該由布局系統在呈現界面時動態完成,而不應該由開發人員靜態完成。

PS做的文字和矢量圖形柵格化成PNG位圖,給人家了,能改嗎,不能改或者很難改。如果給人家PSD原圖,就好改,

用Grid這種動態的布局系統來布局實際上是表達布局思路。實際的大小和位置是由布局系統通過動態計算得到的,即時運算出來的。給布局系統指定布局的依據和參數,讓布局系統自動計算大小和位置,盡量不要手動指定大小和位置。

給布局系統指定布局的依據和參數,讓布局系統自動計算大小和位置,盡量不要手動指定大小和位置。

類似於矢量圖工具指定圖形的參數,呈現時像素是即時運算出來的,而不是像位圖一樣直接存儲像素信息。

WPF等XAML呈現引擎是一個矢量系統,更近一步地說是矢量動畫系統(類似的系統還有Flash,JavaFx,Android等),其使用兩層的方式進行呈現。1.布局系統計算大小位置,2.渲染引擎柵格化成像素顯示。

其他原則

1. Margin是邊距不是坐標,如果需要使用坐標用Canvas。

2. Grid要使用Auto,由內容決定大小,不要手動設置大小。

3. 要使用嵌套Grid替代跨行跨列,但需權衡,嵌套Grid結構好些,思路和邏輯性清楚,好維護,但損失性能,跨行跨列,性能好些。

4. 需要按內容大小自動排列的時候優先用StackPanel,不要用全是Auto的Grid,易於維護。

5. 比例分割剩余空間時,某些行或列,可以用最小或最大寬高進行額外控制,以達到較好的效果。

頁面結構設計

下面列舉出一些常見的頁面結構設計思路。

1. 頁面結構是分層的,一般可分為二至三層。

2. 每一層都可能有標題和內容區之分,最外層可包括頁面標題和內容區,內容區可再分為幾個子區域,每個子區域可分為標題區和內容區兩部分。

3. 如果存在第三層嵌套,和第2層類似,也可再把2級區域的內容區分為幾個子區域,子區域可以有標題。

4. 標題區可能換為工具欄區或兼有工具欄的功能。

5. 區域之間的分割要明顯。

6. 不同的層次要易於區分。

7. 最外層或第二層的區域可使用TabControl提供內容區切換功能。

8. 主視圖和詳視圖或功能切換區和實際內容區一般左右或上下排布。

9. 如出現兩層功能切換的情況,可以第一層左右排布,第二層上下排布。也可第一層上下排布,第二層左右排布。或同為上下排布,功能切換區第一層在上邊,第二層在下邊,避免重復感。

10. 頁面中的一個或多個核心內容區一般為可滾動區域或可縮放區域,要占據頁面最大的空間,要能明顯辯認出。核心內容區不宜過多,避免產生雜亂感。

布局設計模式

從實際工作經驗中,總結出了幾種布局設計模式,和GoF設計模式類似,模式指在某種特定的場景中可以套用的設計方法。

布局設計模式在相似的頁面場景中也可以套用,能達到較好的效果。包括,

局部布局設計模式:

1. 工具欄模式

2. 壓縮空白模式

3. 表單模式

4. 表格模式

5. 工具箱模式

6. 選擇題模式

區域布局設計模式:

7. 頭尾模式

8. 邊欄模式

9. 可變等分模式

10. 文檔模式

11. 圖片模式

從下一篇開始詳細闡述這些模式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM