一个好老好老的老程序员了。
全部博文(915)
分类: Android平台
2019-11-06 10:58:05
响应方向变化
应用程序页面的布局通常与特定的外形和宽高比紧密相关。有时,应用程序将要求仅在纵向或横向模式下使用它。但是,当手机改变方向时,应用程序通常会尝试在屏幕上移动。
网格可以帮助应用程序适应方向更改。可以在XAML中定义网格,对纵向和横向模式都有一定的限制,然后一些代码可以在页面的SizeChanged处理程序中进行适当的调整。
如果您可以将应用程序的整个布局划分为两个大区域,当手机以纵向模式定向或水平定向为横向模式时,此作业最简单。将这些区域中的每一个放在网格的单独单元格中。当手机处于纵向模式时,网格有两行,当它处于横向模式时,它有两列。在下图中,第一个区域始终位于顶部或左侧。第二个区域可以是纵向模式的第二行,也可以是横向模式的第二列:
为了使事情变得相当简单,您需要在XAML中定义具有两行和两列的网格,但在纵向模式下,第二列的宽度为零,而在横向模式下,第二行的高度为零。
GridRgbSliders程序演示了这种技术。它类似于第15章“交互式界面”中的RgbSliders程序,除了布局使用Grid和StackLayout的组合,而Label元素通过使用带有值的数据绑定来显示Slider元素的当前值转换器和值转换器参数。 (稍后会详细介绍。)基于三个Slider元素设置BoxView的Color属性仍然需要代码,因为Color结构的R,G和B属性不受可绑定属性的支持,并且这些属性不能单独更改无论如何,因为他们没有公共集访问器。 (但是,在下一章中,在MVVM上,您将看到一种在代码隐藏文件中消除此逻辑的方法。)
正如您在下面的清单中所看到的,名为mainGrid的Grid确实有两行和两列。但是,它已初始化为纵向模式,因此第二列的宽度为零。 Grid的顶行包含BoxView,使用“*”(星号)设置尽可能大,而底行包含StackLayout和所有交互式控件。这是自动高度:
这是纵向视图:
XAML文件中的布局以两种方式为横向模式准备。首先,Grid已经有了第二列。这意味着要切换到横向模式,代码隐藏文件需要将第二行的高度更改为零,将第二列的宽度更改为非零值。
其次,包含所有Slider和Label元素的StackLayout可以从代码访问,因为它有一个名称,特别是controlPanelStack。然后,代码隐藏文件可以对此StackLayout进行Grid.SetRow和Grid.SetColumn调用,以将其从第1行和第0列移动到第0行和第1列。
在纵向模式下,BoxView的高度为“”(星号),StackLayout的高度为“自动”。这是否意味着StackLayout的宽度在横向模式下应该是Auto?这不是明智之举,因为它会缩小Slider元素的宽度。横向模式的一个更好的解决方案是给BoxView和StackLayout宽度为“”(星号),将屏幕分成两半。
这是代码隐藏文件,显示负责在纵向和横向模式之间切换的页面上的SizeChanged处理程序,以及设置BoxView颜色的Slider元素的ValueChanged处理程序:
点击(此处)折叠或打开
这是横向展示的横向布局:
请注意,特别是在iOS和Android显示器上,每对Slider和Label元素如何组合在一起。这是第三种方式,即XAML文件准备好适应横向模式。每对Slider和Label元素都嵌套在一个嵌套的StackLayout中。这将给出CenterAndExpand的VerticalOptions设置以执行此间距。
稍微考虑安排BoxView和控制面板:在纵向模式下,操纵Slider元素的手指不会遮挡BoxView中的结果,而在横向模式下,惯用右手的用户的手指不会模糊BoxView也是。 (当然,左撇子用户可能会坚持使用程序选项来交换位置!)
屏幕截图显示了以十六进制显示的Slider值。这是通过数据绑定完成的,这通常是个问题。 Slider的Value属性是double类型,如果您尝试使用“X2”格式化十六进制的double,则会引发异常。类型转换器(例如,名为DoubleToIntConverter)必须将源double转换为int以进行字符串格式化。但是,Slider元素的设置范围为0到1,而格式为十六进制的整数值的范围必须介于0到255之间。
解决方案是使用Binding的ConverterParameter属性。设置为此属性的任何内容都作为第三个参数传递给值转换器中的Convert和ConvertBack方法。这是Xamarin.FormsBook.Toolkit库中的DoubleToIntConverter类:
点击(此处)折叠或打开
点击(此处)折叠或打开