嘿嘿嘿,题目比较绕哈。本篇主要讨论一般情况下,页面的布局技巧,怎么将元素的展现尽量做到分辨率无关。基本的思路仍然是尽量少的标定具体的数字,而是用比列来标注各元素占据的空间。

  这里我打算用易信的名片页来举例:

  

  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布局的技巧:

  1. 尽量不要使用具体的数字
  2. 使用Grid来划分行列,通过行列之间的比例来控制整体的布局
  3. 需要保持大小不变的元素,可以使用数值,比如上文的头像
  4. Margin这种不存在相对位置的,仅表示固定间距,大可以写死数值(特别是最外层的Margin)
  5. 总体呈纵向排列的页面,横向可以考虑写数值(因为横向没几个元素,也就没有相对位置的概念),反之亦然。
  6. 暂时就这么多吧,等我想到再补充。

  最后是惯例的彩蛋:俺这个写法支持手机横屏哦,原版就不行的啦。

  GayHub地址:

  https://github.com/manupstairs/UWPSamples

 

 

最新文章

  1. git下载自己项目到本地
  2. 初识 MySQL 5.6 新特性、功能
  3. BestCoder Round #74 (div.2)
  4. Codeforces Round #242 (Div. 2) A. Squats
  5. 利用window.name+iframe跨域获取数据详解
  6. c++操作io常见命令
  7. 越狱Season 1-Episode 7: Riots, Drills and the Devil: Part 2
  8. HTML5 API 之 history
  9. Windows下python环境变量配置
  10. 修改虚拟机内容导致oracle不能启动
  11. PID算法笔记2
  12. 20160213.CCPP体系详解(0023天)
  13. Zigbee技术开发一 设置NV_RESTORE
  14. perl 之 正则表达式 (简)
  15. net core体系-web应用程序-4asp.net core2.0 项目实战(任务管理系统)-1项目说明
  16. Oracle高级查询之over(partition by...)
  17. 微信和QQ内置浏览器为什么老是弹停止访问该网页,微信域名被屏蔽的解决办法
  18. python字符串的魔法
  19. 从零开始学java(二)类与对象
  20. python3接收、解析邮件

热门文章

  1. day12:vcp考试
  2. iOS - push 或 pop或点击导航栏返回pop指定导航控制器
  3. ArrayList与LinkedList的基本添加删除方法 模拟栈 队列
  4. centos7下编译安装php-7.0.15(PHP-FPM)
  5. jquery:为动态加载的元素添加点击事件
  6. HHvm建站环境搭建方法:Nginx,Mariadb,hhvm及lnmp/lamp安装部署
  7. mongodb的安装配置方法
  8. Codeforces 709B 模拟
  9. python不用声明数据类型
  10. 11 Maven 灵活的构建