UWP开发入门(九)——简单界面的布局技巧及屏幕适应
嘿嘿嘿,题目比较绕哈。本篇主要讨论一般情况下,页面的布局技巧,怎么将元素的展现尽量做到分辨率无关。基本的思路仍然是尽量少的标定具体的数字,而是用比列来标注各元素占据的空间。
这里我打算用易信的名片页来举例:

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
UWP开发入门(九)——简单界面的布局技巧及屏幕适应的更多相关文章
- UWP开发入门系列笔记之(一):UWP初览
标签: 随着微软Build2015带来的好消息,Win10正式版发布的日子已经离我们越来越近了,我们也终于欣喜地看到:一个统一的Windows平台对于开发人员来说充满了吸引力,这局棋下的好大的说--于 ...
- UWP开发入门(四)——自定义CommandBar
各位好,再次回到UWP开发入门系列,刚回归可能有些不适应,所以今天我们讲个简单的,自定义CommandBar,说通俗点就是自定义类似AppBarButton的东西,然后扔到CommandBar中使用. ...
- UWP开发入门(25)——通过Radio控制Bluetooth, WiFi
回顾写了许久的UWP开发入门,竟然没有讲过通过Windows.Devices.Radios.Radio来控制Bluetooth和WiFi等功能的开关.也许是因为相关的API设计的简单好用,以至于被我给 ...
- UWP开发入门(十六)——常见的内存泄漏的原因
本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏>中提到过,即使有 ...
- UWP开发入门(十)——通过继承来扩展ListView
本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...
- UWP开发入门(二十)——键盘弹起时变更界面布局
UWP APP在键盘弹起或隐藏时,并不会自动处理界面布局.有时会出现键盘遮挡了下一个需要填写的文本框,或是下一步按钮的情况.本篇我们以登录界面做例子,用一种巧妙简单的方式在键盘弹起和隐藏时更改界面的布 ...
- UWP开发入门(十一)——Attached Property的简单应用
UWP中的Attached Property即附加属性,在实际开发中是很常见的,比如Grid.Row: <Grid Background="{ThemeResource Applica ...
- UWP开发入门(一)——SplitView
接下来会写一个UWP(Universal Windows Platform)开发入门的系列,自己学习到哪里,有什么心得总结,就会写到哪里.本篇对适用于顶层导航的SplitView控件展开讨论. 首先S ...
- UWP开发入门(二十一)——保持Ui线程处于响应状态
GUI的程序有时候会因为等待一个耗时操作完成,导致界面卡死.本篇我们就UWP开发中可能遇到的情况,来讨论如何优化处理. 假设当前存在点击按钮跳转页面的操作,通过按钮打开的新页面,在初始化过程中存在一些 ...
随机推荐
- SQL SERVER 和ACCESS、EXCEL的数据导入导出
SQL SERVER 与ACCESS.EXCEL之间的数据转换SQL SERVER 和ACCESS的数据导入导出[日期:2007-05-06] 来源:Linux公社 作者:Linux 熟 悉 ...
- swift UICollectionView使用
方法1:创建 的时候注册 layout /// 时间view private lazy var timeCollectionV: UICollectionView = { 1.直接注册 并设置好 UI ...
- Halcon的一维条码解码步骤和解码技巧
一.图像预处理和条码增强 对比度太低:scale_image(或使用外部程序scale_image_range),增强图像的对比度. 图像模糊:emphasize锐化图像,使条码看起来更清晰. 深色背 ...
- c++ 对象复制引用时何时调用构造函数、析构函数
class TEST{ private : public : TEST() {std::cout << "constructor" << std::endl ...
- redis缓存设置和读取
一/写入 <?php $redis = new Redis(); //实例化redis $redis->pconnect('); $redis->,'huahua'); //设置变量 ...
- db2 托管事务未设置方法有问题
https://q.cnblogs.com/q/63862
- c++11 stl 学习之 pair
pair以模板的方式存储两个数据 namespace std {template <typename T1, typename T2>struct pair {// memberT1 fi ...
- Selenium安装中的一些问题及解决办法-软硕1703班3组整理分享
非常感谢软件工程硕士1703班3组同学的热心,他们将安装Selenium过程中踩过的坑替大家填上了.希望还没有来得及踩坑的,或者掉进坑里还没爬出来的小组,能顺利跨过去这个安装的坑. 如下是原文. Se ...
- 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)
[描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...
- Redis配置总结
一:常用配置 1.bind,格式为bind 127.0.0.1:这个是很重要的配置,如果bind 127.0.0.1则外部网络是访问不了的(如果外部网络要访问还要开放端口) 2.port,格式为por ...