到目前为止,我们只讨论了如何实现应用程序的行为,而没有讨论它的外观。在本章中,我们将重点讨论这一主题。
版面结构和基础知识
与工作流程类似,应用程序的布局也是用 XML 定义的。布局由LayoutPage
和LayoutModel
组成,前者定义了多个屏幕的可重用框架,后者用于设计特定屏幕的具体细节。此外,我们还可以定义适用于多个布局元素的样式(Style
)和使特定布局部分可重复使用的模板(PartTemplate
)。
所有这些结构元素都在各自独立的文件中定义。当然,它们仍需填充文本、按钮或图片等内容。您可以查看用户界面元素列表来了解概况。
我们的 "选择 "组件的布局页面只包括状态栏、标题和使用<ContentPlaceHolder>
标签的内容部分,该部分将由 "LayoutModel "填充。
<LayoutPage Name="DefaultMaster">
<Part Template="STATUS_BAR" Weight="0.1"/>
<Text Name="Topic" Weight=".15" Style="TitleStyle" Content="Pick a fruit"/>
<Panel Weight="0.75">
<ContentPlaceHolder Name="Content"/>
</Panel>
</LayoutPage>
布局模型 "看起来像这样:
<LayoutModel Name="ChoiceScreen" Page="DefaultMaster" Orientation="Vertical">
<Content PlaceHolder="Content" Weight="1" Orientation="Horizontal">
<Button Name="Apple" FocusOrder="0" Weight="0.5" Style="ImageButtonStyle">
<Text Name="LEFT_TEXT" Style="FooterButtonTextStyle" Weight="1" MaxSize="30" Content="Apple"/>
<Events/>
</Button>
<Button Name="Pear" FocusOrder="1" Weight="0.5" Style="ImageButtonStyle">
<Text Name="RIGHT_TEXT" Style="FooterButtonTextStyle" Weight="1" MaxSize="30" Content="Pear"/>
<Events/>
</Button>
</Content>
</LayoutModel>
"LayoutModel" 是我们与工作流连接的元素。这是在定义工作流的一个步骤时完成的:<step id="choose" descriptor="用户在两个选项中进行选择" uitemplate="ChoiceScreen">。
如上图所示,"LayoutModel "会引用Page="DefaultMaster
来获取其外层框架。然后从 "LayoutPage "引用<ContentPlaceHolder Name="Content
"/> 使用<Content PlaceHolder="Content"....
尺寸和方向
根据用户界面元素的类型,您可以使用一系列属性来按照自己的喜好设计用户界面。首先要注意的两个属性是权重
和方向
,因为它们可以帮助你设计用户界面的总体结构。
权重
定义了元素的大小,范围在 0 和 1 之间,其中 1 是父元素大小的 100%。方向
应用于父元素,并决定子元素在父元素中是水平
(彼此相邻)还是垂直
(彼此位于顶部)。
在上述 "LayoutModel"(布局模型)中,Content
元素具有水平
方向,因此按钮将紧挨着显示。每个按钮都可以使用"内容
"元素可用大小的Weight="0.5"
(即 50%)。而按钮内的文本元素则使用其父元素(按钮)的全部可用空间,Weight="1"。
通常,在设置元素的大小和方向时,使用面板
元素会有所帮助。这些元素纯粹是结构性的,可用于轻松改变父元素的方向或细分其空间。
按钮和聚焦顺序
在使用按钮时,有一个属性尤为重要:FocusOrder
属性。该属性定义了使用硬件按钮翻页时按钮的聚焦顺序。它还定义了哪个按钮将被预选,即FocusOrder="0"
的按钮。
布局中的每个按钮都需要有不同的FocusOrder
。即使有些按钮是在部件模板中,因此是在不同的文件中,它们仍然需要按照布局的整体顺序排列。
提示和技巧:布局的 FocusOrder 必须从 0 开始,并且是连续的,不能有任何间隙或重复。否则,您的应用程序在尝试加载布局时很可能会崩溃。如果您在开发过程中遇到过应用程序突然崩溃的情况,那么您应该立即想到验证 FocusOrder。
布局变化
显示给用户的内容很少是一成不变的。任何用户交互通常都会导致用户界面发生变化。当然,我们不希望每次文本字段的内容发生变化时,都要创建新的布局和步骤。有两种方法可以动态调整用户界面:在工作流中创建<mapping>
和使用ui_update
操作。
制图
通过映射,可以将一个值或变量与用户界面元素的一个属性永久关联起来。如果你映射了一个变量,每当变量值发生变化时,用户界面元素的属性就会自动改变。
<step ...>
<states>...</states>
<mapping>
<ui_element name="LEFT_TEXT">
<param name="content">#{left_option}</param>
<param name="text_color">#{option_color}</param>
</ui_element>
</mapping>
</step>
上例显示,映射是作为步骤标记的子标记添加的。您可以在此添加任意数量的 ui_element 标签,这些标签将引用布局中的用户界面元素。在本例中,name="LEFT_TEXT
,按钮的文本代表我们的第一个选项。只要在工作流中更改变量#{lef_option}
,用户界面就会在该按钮上显示不同的文本。
ui_update 操作
另一种动态更改布局的方法是ui_update
操作。该操作可对布局进行一次性更改:
<ui_update id="change_left_button_text">
<widget_params>
<ui_element name="LEFT_TEXT">
<param name="content">#{left_option}</param>
<param name="text_color">#{option_color}</param>
</ui_element>
</widget_params>
</ui_update>
在大多数用例中,最好是直接设置映射而不是使用此操作。但是,有一种情况下,映射不起作用,您必须使用ui_update
操作:
映射内的 JavaScript 只执行一次,因此如果需要使用 JS,且值在步骤的生命周期内发生变化,则必须使用ui_update
操作手动更新用户界面。
可以使用.html
标签对智能眼镜中显示的文本进行格式化。您可以将格式化添加到用户界面模板、布局文件或组件中,同时在代码中创建新文本。
<Text Name="LEFT_TEXT" Style="FooterButtonTextStyle" Weight="1" MaxSize="30" Content="<h1>Red Apples taste the best</h1> green Apples<br>are not so <sub>tasty</sub>"/>
格式化的结果可能因所分配的布局组件和特定组件的配置而异。
请参阅工作流引擎参考部分的文本格式 。
任务
作业 1:
到目前为止,我们已经在两种文字选项中做出了选择。现在,我们要在其中加入图像:
- 为按钮添加图像 UI 元素。
- 将以下图片添加到工作流程资源中(从高级编辑器中)。
- 您只需将资源列表中的图片拖放到图片标签的
contentattribute
中即可。
下载组件(作业前)
帮助与资源
下载两个项目的图片。
解决方案
下面是一个示例解决方案:
<Button Name="Apple" FocusOrder="0" Weight="0.5" Style="ImageButtonStyle">
<Image Name="LEFT_IMAGE" Weight="0.8" Margin="0,0,0,0" Content="§{apple.jpg}§" ScaleType="CenterCrop"/>
<Text Name="LEFT_TEXT" Style="FooterButtonTextStyle" Weight=".2" MaxSize="30" Content="Apple"/>
<Events/>
</Button>
<Button Name="Pear" FocusOrder="1" Weight="0.5" Style="ImageButtonStyle">
<Image Name="RIGHT_IMAGE" Weight="0.8" Margin="0,0,0,0" Content="§{pear.jpg}§" ScaleType="CenterCrop"/>
<Text Name="RIGHT_TEXT" Style="FooterButtonTextStyle" Weight=".2" MaxSize="30" Content="Pear"/>
<Events/>
</Button>
下载组件(作业后)
在下一课中,你将学习如何使组件可配置,从而使其真正成为可重复使用的组件。