嘿嘿嘿,題目比較繞哈。本篇主要討論一般情況下,頁面的佈局技巧,怎麼將元素的展現儘量做到解析度無關。基本的思路仍然是儘量少的標定具體的數字,而是用比列來標註各元素占據的空間。 這裡我打算用易信的名片頁來舉例: Phone的界面看起來不錯,大致以縱向排列。最上方是標題欄,頭像部分居中,下麵的文字以列表形
嘿嘿嘿,題目比較繞哈。本篇主要討論一般情況下,頁面的佈局技巧,怎麼將元素的展現儘量做到解析度無關。基本的思路仍然是儘量少的標定具體的數字,而是用比列來標註各元素占據的空間。
這裡我打算用易信的名片頁來舉例:
Phone的界面看起來不錯,大致以縱向排列。最上方是標題欄,頭像部分居中,下麵的文字以列表形式靠左對齊,最下部為留白。考慮到標題欄需要錨定在頂部,不參與比例分配。頭像,文字和留白的占比大致為2.5:4:3。XAML中的Grid定義如下:
<Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="2.5*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="3*"></RowDefinition> </Grid.RowDefinitions>
按比例而不是寫死每一行的高度,好處在於屏幕大小變化時,甚至屏幕的縱橫比變化時,各元素能按相對位置來佈局,減少了因為屏幕空間不夠而截斷或互相遮蓋的問題。
看過了總體的縱向比例,再確認第0行的標題欄的橫向佈局。三個元素要以左左右的順序排列。這裡給出一種方案:
<Grid Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> </Grid.ColumnDefinitions> <FontIcon Grid.Column="0" Glyph="" /> <TextBlock Grid.Column="1" Style="{StaticResource SubtitleTextBlockStyle}" HorizontalAlignment="Left">個人名片</TextBlock> <TextBlock Grid.Column="2" Style="{StaticResource CaptionTextBlockStyle}" VerticalAlignment="Center" >編輯</TextBlock> </Grid>
再來是頭像部分,共分四行,最上留白(不用Margin是因為考慮橫屏的時候,Margin寫死數字會相對占用很大的空間),頭像,姓名和易信號。
<Grid Grid.Row="1"> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Ellipse Grid.Row="1" Width="60" Height="60" > <Ellipse.Fill> <ImageBrush ImageSource="Assets/xingzheng.jpg" ></ImageBrush> </Ellipse.Fill> </Ellipse> <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" VerticalAlignment="Center">邢政</TextBlock> <FontIcon Glyph=""></FontIcon> </StackPanel> <StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Style="{StaticResource BodyTextBlockStyle}" Foreground="LightGray">易信號:</TextBlock> <TextBlock Style="{StaticResource BodyTextBlockStyle}" Foreground="LightGray">manupstairs</TextBlock> </StackPanel> </Grid>
這裡可以看到頭像Image的Width和Height寫死了。這是考慮到頭像應該和文字一樣保持大小不變,而不是頭像根據屏幕縮放,在整個頁面字型大小不改變的情況下,單獨變頭像感覺會比較奇怪。
再往下的列表和留白比較簡單,不多做介紹,直接放出Phone頁面的效果圖和原版對比:
看小圖幾乎一模一樣了,當然易信的圖標俺沒有,俺用的系統自帶的。
既然要Adaptive UI,自然要能無縫切換到PC模式,還是先看原版截圖。
PC的部分依然是同樣的佈局,但因為縱橫比例反過來了,所以橫向自適應的部分將右邊整個畫面拉寬了。截圖是視窗模式,如果放到全屏,右邊會越發的寬。
這種保持元素尺寸及相對位置不變,將背景進行橫向或縱向的拉伸實現的自適應佈局是最為常見的。
我們之前的代碼基本不存在寫死的數值,都是按比例佈局。所以無需修改直接將視窗拖大看看效果吧。
平移上去比對可以看到效果基本是類似的。那是不是本文到這裡就結束了呢?曾經我以為是,感覺Adaptive UI一般做到這種程度就可以了。最多只是細節上調一調,整體佈局是不會動的。
但是美術不是這樣的想的啊,她們突發其想說PC上我要下麵這種效果,系統自帶的喲……
PC我要靠左對齊……靠左……靠左……當時感覺頭要炸了。介於平時我的宣傳口徑是“沒有不能做的”。這尼瑪硬著頭皮也要上啊。仔細想想也很簡單啊,加一層VisualState就可以了啊:
<VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState > <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="769" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="GridRootLayout.HorizontalAlignment" Value="Left"></Setter> <Setter Target="GridRootLayout.VerticalAlignment" Value="Top"></Setter> <Setter Target="GridRootLayout.Width" Value="320"></Setter> <Setter Target="GridRootLayout.Height" Value="640"></Setter> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>
這裡的769是針對1520這樣的1080p 6寸機器。目前常見的機型中就1520 Width最大達到了768這個數值。769就成了區分手機和PC,Tablet的分界值。效果圖如下,相當於把720p機型的屏幕複製過來貼靠到左上角顯示:
至於有沒有比剛纔更好看麽,美術說了算。
大體上就是這樣吧,最後必須得總結一下XAML UI佈局的技巧:
- 儘量不要使用具體的數字
- 使用Grid來劃分行列,通過行列之間的比例來控制整體的佈局
- 需要保持大小不變的元素,可以使用數值,比如上文的頭像
- Margin這種不存在相對位置的,僅表示固定間距,大可以寫死數值(特別是最外層的Margin)
- 總體呈縱向排列的頁面,橫向可以考慮寫數值(因為橫向沒幾個元素,也就沒有相對位置的概念),反之亦然。
- 暫時就這麼多吧,等我想到再補充。
最後是慣例的彩蛋:俺這個寫法支持手機橫屏哦,原版就不行的啦。
GayHub地址:
https://github.com/manupstairs/UWPSamples