需要的其他产品
- Android 2.2及更高版本或Android 3.0及更高版本的设备
仅仅在Flash Builder 4和Flex 4 SDK发布一年后,新的Flash Builder 4.5和Flex 4.5 SDK版本就已面世!Flex 4.5 SDK和Flash Builder 4.5的关注重点是构建以Google Android、Blackberry Tablet OS和Apple iOS操作系统为目标的移动应用程序的能力。此外,Flex 4.5 SDK针对大型应用程序开发引入了新的Spark组件和改进,而Flash Builder 4.5引入数十个新的编码生产力功能,以提高ActionScript和MXML开发速度。要了解Flex 4.5 SDK中的新功能和改进功能的更多信息,请查阅 Deepa Subramaniam 的文章。此外,要了解Flash Builder 4.5中的新功能,包括新的面向开发人员的功能以及使用Flash Catalyst CS 5.5的新工作流,请查阅 Andrew Shorten的文章。如果您希望具体了解Flex 4.5 SDK和Flash Builder 4.5中新的移动功能,请查阅 Narciso Jaramillo的概述文章。
在本文中,我将介绍如何构建同时适合传统Web和移动部署的应用程序。我们将探讨我们所构建的3个参考应用程序,其中每个应用程序既可在浏览器中作为传统的Web应用程序运行,又可以在移动设备上运行。这3个应用程序是 Shopping Cart, Expense Tracker 和 Sales Dashboard 应用程序。我们将介绍在为移动和平板设备以及Web构建Flex应用程序时的具体考虑因素。此外,我们还将介绍我的团队如何搭建应用程序,以在Web和设备项目之间共享代码。最后,我们将探讨在为所有形式的环境构建应用程序时应该考虑的性能因素。
创建新Flex Mobile项目
除了支持Flash Builder 4中可用的所有项目类型,Flash Builder 4.5还引入了其他Flex项目类型,包括Flex Mobile项目和ActionScript Mobile项目。这些移动项目针对移动应用程序开发进行了调节。Flex Mobile项目能够理解适用于移动设备的移动“安全的”Flex组件。此外,Flash Builder 4.5在创建新移动项目时可为您提供帮助,无论是Flex Mobile还是ActionScript Mobile项目。要创建新Flex Mobile项目,请转到 File > New > Flex Mobile Project。 您将看到Flash Builder会帮助您执行创建和配置一个新的移动项目,包括它的名称和您希望构建的移动应用程序类型。Shopping Cart、Expense Tracker和Sales Dashboard移动应用程序都使用基于视图的应用程序类型。这意味着应用程序的每个视图都有其自己的View类控制,所有视图都由一个ViewNavigatorApplication 控制。Shopping Cart和Expense Tracker平板应用程序也由ViewNavigatorApplication控制。但是,Dashboard平板应用程序是一个标准的AIR应用程序,使用一个SplitViewNavigator来管理它的视图。
Flash Builder 4.5将帮助为您基于视图的应用程序创建存根视图。您然后可以添加您应用程序的后续视图。每个存根视图从spark.components.View类派 生而来。视图可理解如何显示数据并将信息注入到动作栏(Action Bar)。动作栏是每个应用程序顶部的导航UI。这提供了当前视图的上下文信息,包括当前视图的标题和可将用户导航到应用程序内的特定位置的动作按钮。
Shopping Cart移动项目将其所有子视图组织到 com.adobe.mobileshoppingcart.view 包中。您可在其中看到为Shopping Cart移动应用程序内的每个后续视图创建UI的MXML类。例如,CartView.mxml 是用户选择了要购买的商品后的结算视图,或者ItemDetailsView是各个商品的细节视图(参见图1)。
专为在多个屏幕间实现最高代码重用率而设计
Flash Builder 4.5为您提供了为各种不同的项目目标(包括针对使用Adobe Flash Player部署的Web,或针对使用Adobe AIR部署的桌面、平板设备或移动设备)开发应用程序所需的所有工作流。针对我们的团队,我们决定在构建Shopping Cart、Expense Tracker和Sales Dashboard应用程序的Web和设备版本时使用一种应用程序体系结构。此应用程序体系结构非常适合跨开发团队组织代码,以及保持UI代码与服务层代 码分离。此外,此体系结构还允许我们在Web和移动项目之间共享代码。(注意:没有必要使用一种应用程序体系结构来在Web和移动项目之间共享代码,但对 于我们这样的分布式开发团队,事实证明应用程序体系结构很有用)。
我们选择的体系结构比较松散,基于一种经典的模型-视图-演示器(MVP)体系结构。MVP使用被动视图,利用一种正式的控制器来在视图之间传递状态和UI信息。通过将所有逻辑代码保存在视图文件外部,我和我的团队能够在多个项目中重用核心应用程序代码。
FXP与FXPL对比
将在多个项目之间(在我们的示例中,在Web项目与移动项目之间)共享的核心应用程序代码全部包含在一个Flex Library Project(FXLP)中。例如,MobileShoppingCart.fxp、ShoppingCartTablet.fxp和 ShoppingCartWeb.fxp都链接到ShoppingCartLib.fxpl中。ShoppingCartLib.fxpl包含所有在 Web和设备版本之间共享的相关代码,包括服务层和实用程序类。类似地,DashboardMobile.fxp、 DashboardTablet.fxp和DashboardWeb.fxp都链接到DashboardLib.fxpl和 DashboardChartLib.fxpl中。这些FXPL包含在Sales Dashboard Web和设备应用程序中处理图表组件和数据管理的共享代码。最后,CRUDMobile.fxp、CRUDTablet.fxp和CRUDWeb.fxp 链接到共享库项目CRUDLib.fxpl中。
当使用一个Flex Library项目时,一般的经验规则是,数据模型、控制器、服务、事件和实用程序类都应包含在内。一般而言,库项目不应包含任何特定于UI的代码,除非 可以在不同类型的环境*享该UI。像MobileShoppingCart.fxp这样添加特定于移动的UI代码是Flex Mobile项目的责任,像ShoppingCartWeb.fxp这样添加特定于浏览器(或桌面)的UI的代码是Flex项目的责任。这一实践有助于确保跨不同的环境出色地封装和重用通用代码。
演示器
演示器是应用程序体系结构中的重要部分。应用程序的每个功能状态都有一个presenter类。演示器的实例注入到视图文件中,既可通过使用Swiz等框 架进行元数据注入,从一个单一实例模型引用,也可以通过构造函数传入演示器。在上面列出的示例项目中,主要类的演示器实例从一种单一实例模型引用,而项目 呈现器的演示器在控制器类中动态创建。例如,MobileShoppingCart.fxp中的ItemDetailsView.mxml类在第36行具有对一个presenter变量的引用。视图正是从这个presenter对象引用了应用程序的业务逻辑。类似地,每个Web和移动应用程序的List组件显示了一组presenter对象。MobileShoppingCart.fxp的MainView.mxml中的List控件显示了用户正在查看的一组项。这些数据项是视图显示的presenter对象。
视图显示的所有属性由演示器持有。演示器通过事件与视图通信。这就是每个presenter类都扩展EventDispatcher的原因。请查阅ShoppingCartLib.fxpl项目中包含的ItemPresenter类(com.adobe.shoppingcart.presenter)。请注意,ItemPresenter扩展了EventDispatcher,并在有内容发生更改时分派事件。通过这种方式,演示器公开一个公共方法API,视图可调用该API来适当地显示UI。
演示器持有它用于分派事件的IEventDispatcher对象的实例,在本例中为控制器实例。这是演示器与应用程序的业务逻辑部分通信的方式。演示器从不持有控制器的实例,或者在此过程中执行函数调用。为了保持封装,演示器仅分派事件。事件是演示器与控制器之间的契约。
控制器
控制器控制应用程序的不同部分之间的通信。应用程序状态决策在控制器内制定。在应用程序启动时,会创建控制器的一个实例。在示例项目中,请查阅WebShoppingCart.mxml和MobileShoppingCart.mxml中的preinitalizeHandler。这是为Shopping Cart应用程序的Web和移动版本创建控制器的地方。控制器创建presenter对象的实例并将它们存储在模型中。此外,控制器还设置模型上的所有属性。
控制器还监听来自演示器的事件。例如,当演示器触发一个事件来更改当前屏幕时,控制器会处理该事件。控制器然后就应该如何处理演示器的请求而指定逻辑决策。控制器可以调用服务层或直接在演示器上设置属性。
需要在多个演示器之间保持同步的属性有时缓存在模型中,但在大多数情况下,每个演示器持有自己的状态和属性。如MVP所述,您完全可以让模型来持有状态并能够向演示器广播状态更改,但就我的经验来讲,这只会增加复杂性,而没有任何好处。
在少数情况,我会发现控制器的行为需要因项目目标不同而不同。在这些情况下,我扩展控制器并改写需要自定义实现的方法。这个扩展的控制器是我在对特定项目类型进行主要初始化期间实例化的类。
视图
视图代码常常不会在不同类型项目之间共享。但是,Flex Mobile项目可以包含特定于移动的UI,Flex项目包含非特定于移动的UI。这样,用户界面可针对运行应用程序的具体环境而调节。
为您的应用程序需要支持的每种目标屏幕创建一个新FLex或ActionScript项目。类似的目标屏幕,比如移动电话和平板电脑,可能能够使用相同的项目,具体取决于您应用程序的需要,但Flex确实支持专门针对智能电话和平板电脑创建UI。
特定于视图的UI代码(MXML文件、CSS样式表、图像和字体等资产)应该在每个项目中创建。尽管大部分视图代码都是专门针对项目的目标环境而创建的, 但所有核心应用程序代码都可以共享。您在项目中创建的每个新视图将能够通过演示器与应用程序的剩余部分通信。因为视图中没有保存逻辑代码,所以在项目之间 复制视图中的代码的需要极少。相反,您可以绑定到演示器上的属性,在演示器上调用方法来响应用户手势。
模型
模型用于存储演示器的实例。演示器的实例同时从控制器和视图引用。模型持有演示器的实例,所以控制器和视图都可以访问相同实例。
视图绝不应该引用模型中的属性。相反,视图仅应了解此演示器(以及可能一个状态枚举或某种类似声明)。直接从视图引用模型对象会破坏封装模式。简单来讲,视图应该知道的唯一的契约就是演示器的契约。
如果您在使用Swiz等框架,您可以将演示器注入到您的视图中,而放弃在模型中持有它。Swiz框架会为您创建和管理演示器的实例。
服务层
我强烈建议使用由一个接口定义的服务委托。这支持轻松切换到不同的服务实现,而不更改任何其他应用程序代码。如果您在应用程序开发的初始阶段开发模拟或还未完成的服务,这种方法将特别有用。
在我使用的体系结构上下文中,控制器持有服务对象的实例。控制器在服务对象上进行调用并监听响应。我们使用AsyncToken作为监听结果的服务契约; 在这种情况下很容易获得故障。在CRUDTablet.fxp中,如果您查看ExpenseItemsSQLLiteService.as,可以看到此方 法允许我们轻松切换到使用SQLLite存储我们的数据。
设计和实现您的应用程序UI
您可以与设计者合作实现您应用程序的UI的观感和交互模式,无论它针对的是Web、移动、平板还是桌面。我们的团队与设计者合作设计了每个视图,尤其是针 对移动和平板项目。我们的设计者深入考虑了用户将如何与运行应用程序的移动或平板设备交互、各种不同设备的屏幕大小和每英寸密度,以及用户在使用移动或平 板设备时熟悉的导航模式。有了所有这些信息,以及Flex提供的便利性,我们能够完成既在视觉上富有吸引力,又易于通过Flex实现的设计。
与设计者合作
优秀的用户体验设计者和视觉设计者可将应用程序从“不错”提升到“惊艳”。设计者和开发者之间的良好沟通需要在形式和功能上实现平衡,这可能带来不仅易于 使用,而且具有漂亮外观和功能的应用程序!在我的经验中,许多组织将用户体验设计与视觉设计混淆在一起。在许多时候,用户体验设计者的角色被忽略了,这一 任务落在视觉设计者或开发者头上。用户体验设计者将时间用于分析应该如何与应用程序交互,包括数据和应用程序状态的显示和导航。在我的经验中,有专门的设 计者或负责用户体验的专家的项目会实现更优秀的软件。
在我们的项目中,Web项目都拥有由视觉设计者在Adobe Illustrator CS5或Adobe Fireworks CS5中创建的线框图。线框图然后转换为功能性的Flex代码,这通过使用Flash Catalyst CS 5.5来完成,或者使用开发人员基于视觉设计者提供的线框图为Flex组件亲自设计的Spark皮肤来完成。此外,Flash Builder Wireframe主题非常适合在早期阶段草拟应用程序的简单UI。要了解如何使用Flash Builder 4.5和Flash Catalyst CS 5.5来为您的项目开发皮肤和资产的更多信息,请查阅Jacob Surber编写的这篇文章。
皮肤
Flex 4引入的皮肤体系结构使创建自定义视图变得非常简单,无论它是用于移动还是Web项目。要了解这个名为Spark的新皮肤体系结构,请查阅这篇概述文章。
Flex 4.5 SDK在Spark基础上构建了它的所有移动组件和功能。所有这些组件都针对在Flex SDK 4.5中使用进行了优化,包含特殊的移动皮肤。出于性能原因,这些皮肤是在ActionScript中创建的。这些移动皮肤是轻量型的,但没有公开与默认 Flex 4皮肤那么多的样式。对于大部分移动项目,我们在ActionScript 3中创建了新屏幕,但是,我们可以在一些地方使用MXML皮肤。一般的经验规则是,基于MXML的Flex Mobile项目皮肤非常不错,尤其是在很少使用时。但是如果您要考虑性能问题,切换到基于ActionScript的皮肤有望实现更高性能。因为平板设 备通常拥有更快的处理器,所以与电话应用程序相比,我们可以为皮肤使用更多MXML。对于大部分Shopping Cart、Expense Tracker和Dashboard移动项目,当为移动组件创建新皮肤时,我们扩展了默认的移动ActionScript皮肤,而不是使用默认的MXML 皮肤。
通常,在皮肤文件中程序化地编写绘图代码是将视觉设计转换为Flex的最佳方式。乍看起来这可能很单调,但尽管一段时间后,它将变成第二特性。这还意味着 您拥有高得多的性能!在大多数情况下,在皮肤文件中手动绘制代码会得到比嵌入式资产漂亮得多的皮肤。即使您不希望使用纯ActionScript来完成此 任务,也可以使用FXG。一般而言,建议在Flex Mobile项目中使用FXG。请注意,Shopping Cart项目中的大部分皮肤都是使用FXG创建的。以这种方式创建的皮肤更小且更容易在整个应用程序生命周期内维护。
对于无法通过FXG轻松地重新创建的作品,有必要使用外部资源。尽管Flex支持加载和嵌入许多类型的资产,但一些格式可能比其他格式更适合。对于静态矢 量资产,FXG是最佳的选择。对于静态位图,JPG文件可能是最小且最容易使用的图形。在可能时,具有透明度的位图应该重新创建为矢量图。这是一条不错的 性能提升技巧。一般而言,鼓励视觉设计者使用更少位图是种不错的做法。
为Web和设备项目创建快速列表
数据感知的控件很重要,常常用在Flex项目中。在所有移动参考项目中。列表用于显示数据,用户与列表交互来深入操作应用程序。类似地,Web项目使用列表和其他类似列表的组件来向最终用户显示数据和上下文信息。
Spark List组件针对Flex 4.5 SDK中的移动用途进行了优化。此外,Flex 4.5 SDK中首次推出了一种Spark DataGrid。在两种情况下,都需要理解如何创建高性能的项目呈现器供组件用于显示数据。项目呈现器常常是影响交互性及列表和基于列表的组件的平滑性 的主要罪魁祸首。此外,您可能希望避免向列表中添加DropShadow等滤镜,因为整个列表在滚动时必须缓存为位图。以下各节将介绍创建高性能项目呈现 器供Spark Lists和Spark DataGrids使用的技巧。
在Web Shopping Cart应用程序中编写快速的呈现器
项目迭代器是一个类,它定义来显示绑定到基于列表的组件的数据。当滚动Spark列表时,项目呈现器会非常频繁地重新绘制。这种重新绘制有时可能延缓您应用程序的速度。如果花时间编写有效且智能的项目呈现器,将显著改善您的移动或非移动应用程序中的列表的滚动体验。
在Shopping Cart Web项目中,我们使用多个自定义项目呈现器。看一下ShoppingCartWeb.fxp项目中的 ItemPreviewListRenderer.mxml。请注意,这个项目呈现器没有无关的FXG的元素,它没有过度使用数据绑定,而且它也没有嵌套 太多容器或组。这些都是创建高性能项目呈现器的不错技巧,无论用于移动还是非移动列表。
Spark List组件默认将属性useVirtualLayout设置为true。这意味着项目呈现器将在将新数据项滚入视图中时得到重用。这在显示和导航较长的数据列表时非常有用。
当创建或回收一个项目呈现器时,该数据属性设置为需要显示的新项。为了管理这一数据设置,您需要改写数据属性的setter。在ItemPreviewListRenderer.mxml中, 您将会注意到,该数据属性实际上是一个presenter对象的实例。当设置时,该数据属性转换为一个ItemPresenter,然后设置为 presenter类属性。这个视觉组件进而绑定到演示器中的属性,并在该演示器上执行方法调用。这是将演示器用于封装逻辑的一个非常不错的例子。
在Mobile Shopping Cart应用程序中编写快速呈现器
当开发Shopping Cart移动项目时,我们在优化每个包含Spark List组件的视图中使用的项目呈现器上投入了大量精力。不建议将默认Flex ItemRenderer类(您可能习惯于在Web和桌面Flex项目中使用它)用于Flex Mobile项目中。相反,引入了新的项目呈现器类,它们专门针对移动领域进行了优化。这包括LabelItemRenderer(一个用于显示一行文本 的默认移动呈现器)和IconItemRenderer(一个用于显示文本和图像的默认移动呈现器)(参见图2)。
LabelItemRenderer
您在为用于Flex Mobile项目中的列表组件创建简单的文本项呈现器时使用的基类是LabelItemRenderer。LableItemRenderer扩展了UIComponent并比ItemRenderer小得多,因为ItemRenderer扩展自Group,因此更加复杂。LabelItemRenderer是移动Flex项目中的列表组件的默认项目呈现器。它呈现单个文本元素,如上面的屏幕截图所示。LabelItemRenderer继承了在父List组件上设置的labelField属性,在一个名为标签的文本元素中显示文本。该标签是StyleableTextField的一个实例。StyleableTextField扩展了TextField,从名称可以看出,它提供了一种应用CSS样式来控制文本显示的机制。尽管TLF文本非常适合在Web和桌面应用程序中使用,但TextField的执行性能在移动场景中好得多。TextField在移动应用程序中滚动包含大量文本的元素时特别有用。
选择LabelItemRenderer可开箱即用的实现最快的滚动性能。当编写您自己的项目呈现器时,可以从LabelItemRenderer派生子类。一般而言,可以复制在LabelItemRenderer中使用的实践和原则(比如编程代码),以处理度量和布局以及对数据绑定的过量使用的敏感性。
IconItemRenderer
IconItemRenderer扩展自LabelItemRenderer。除了LabelItemRenderer提供的文本显示,IconItemRenderer还提供了其他显示元素,比如:
- 标签
- 消息
- 图标
- 修饰符
- 图标占位符
标签元素与LabelItemRenderer中相同,显示绑定到呈现器的文本。消息显示元素是一个辅助(和可选的)文本显示元素,也是StyleableTextField的一个实例。
图标显示元素是BitmapImage组件的一个实例。BitmapImage已在Flex 4.5 SDK中得到了改进,具有更高的性能,因为它可缓存它所显示的视觉资产。图标元素是默认显示在项目呈现器左侧的图像,如上图所示(参见图3)。
修饰符元素也是BitmapImage的一个实例。它常常设置为V形图标,默认显示在呈现器的右侧。建议将修饰符设置为嵌入式图像资产,以实现最高的性能。
图标占位符也是BitmapImage的一个实例。它是在加载图标图像或丢失图标图像时显示的图像。像修饰符一样,建议嵌入图标占位符资产以实现最优性能。
当您需要为移动列表自定义项目呈现器时,您有3个选项:扩展UIComponent、扩展LabelItemRender或扩展IconItemRenderer。在Shopping Cart移动项目中,请查阅com.adobe.mobileshoppingcart.view.renderer包中的ItemPreviewImageRenderer.as。这个项目呈现器扩展自IconItemRenderer,利用了所定义的现有的显示元素。我仅设置了必要的属性,具有平滑的滚动列表。
使用Spark DataGrid
在Expense Tracker Web项目中,我们使用了Flex 4.5 SDK中新增的Spark DataGrid。Spark DataGrid相对于MX DataGrid拥有多项改进。它通过一个内容丰富的Spark皮肤协议全面支持视觉自定义。此外,Spark DataGrid还支持针对同时适合页眉和项目的呈现器,全面支持高级的列功能,比如大小调整和排序,即可全面访问又可编辑。您可查阅 CRUDWeb.fxp中的DataGridView.mxml,了解DataGrid的实际应用。
定义DataGrid的列
Spark DataGrid有一个类型为IList的columns属性。columns列表应该包含GridColumn对象。在Expense Tracker Web应用程序中,用户能够通过一个设置控件打开和关闭列。
在上面提及的体系结构中,演示器持有视图的所有状态。在这种情况下,演示器持有当前由用户“打开”(可见)的列列表。因为GridColumn归为视图对象类别,所以GridColumn不满足添加到共享的CRUDLib库项目来与Expense Tracker移动项目共享的标准。
为了解决此问题,我创建了一种新接口和模型对象:
IGridColumnModel和GridColumnModel。IGridColumnModel是一种仅包含数据的GridColumn视图对象表示,主要的演示器类持有columnList ArrayCollection中的一组GridColumnModel对象。该视图进而监听对columnList ArrayCollection的更改,然后使用一个自定义工厂类来构建GridColumn视图对象的实例。这个工厂类名为GridColumnFactory,有一个名为buildGridColumn()的静态方法,该方法获取一个IGridColumnModel对象并返回一个GridColumn。这允许所有视图代码保留在合适的项目中,状态仍然保存在共享的演示器代码中。
与其他项目呈现器一样,在创建DataGrid项目呈现器时应该考虑效率。以下是创建高性能DataGrid项目呈现器的一些技巧:
- 在GridColumn内构建任何格式化器对象,而不直接在项目呈现器中构建它。这将减少需要创建的格式化器对象的数量,此外,GridColumn拥有对应用格式化器的原生支持。借助该支持,项目呈现器的标签属性将由GridColumn格式化。
- GridItemRenderers应该使用prepare()方法,而不设置数据来初始化呈现器和处理更新。
- 不要过度嵌套容器或向DataGrid的项目呈现器中添加不必要的显示元素。精减保持针对任何项目呈现器的显示列表是改善性能的关键。
在Web和移动项目中使用MX图表
Flex Mobile项目需要Spark组件,不过有一个例外,那就是允许使用MX图表组件,比如ColumnChart、BarChart、PieChart等。 当在Flash Builder 4.5中创建新Flex Mobile项目时,图表组件已包含在项目的库路径中,所以这些组件可直接用于代码提示和设计视图中。Sales Dashboard Web和移动项目都使用了图表组件来显示财务信息。共享的数据层以及共享的UI图表组件都包含在DashboardChartLib.fxpl中。这是在 Web和移动项目之间通过单一Flex Library项目共享UI代码的示例。除了图表组件,DashboardMobile.fxp和DashboardWeb.fxp包含所有特定于Web 或移动环境的UI代码(比如特定于移动环境的项目呈现器)。
将SplitViewNavigator用于平板应用程序
平板应用程序的一种通用布局模式是大纲/细节布局。如果查看DashboardTablet.fxp项目,您将看到此布局的实际应用。当应用程序处于横向 模式时,左侧有一列小视图。单击一个小视图会在右侧打开较大的细节视图。当应用程序出于纵向模式时,左侧列会消失,较大的细节视图将填满整个屏幕。较小的 大纲视图的列现在可通过屏幕左上角的CalloutButton访问。此布局可轻松地实现为SplitViewNavigator容器。
查看DashboardTablet.mxml,您将看到根mxml标记是一个Application标记,而不是在其他平板项目中看到的 ViewNavigatorApplication标签。这是因为没有SplitViewNavigator应用程序类型。我们仍然能够使用 ViewNavigatorApplication的元素,使用NavigatorContent容器来持有我们的顶部导航元素。除了 NavigatorContent容器,您还将看到SplitViewNavigator容器。
在SplitViewNavigator的属性内,我们可以指定纵向和横向状态下的布局,以及我们是否希望自动在纵向模式下自动隐藏第一个视图导航程序。 这个SplitViewNavigator的内容是两个ViewNavigators。一个用于大纲视图,一个用于细节视图。这些 ViewNavigator可能分配了第一个视图,以及将视图推送到其中或在其中弹出,就像传统的移动应用程序一样。您可在 DashboardTablet MXML文件顶部的goStateHandler中看到一个相关示例。
为平板设备上的菜单使用CalloutButton
在CRUDMobile.fxp和DashboardMobile.fxp应用程序中,我们创建了一个扩展 SkinnablePopUpContainer的自定义MultiSelectList组件,以创建一个模态的全屏菜单,以允许用户选择一个选项。尽管 此方法非常适合电话设备,但它不是很适合平板设备。使用平板设备,我们拥有多得多的空间,所以一个具有少量选项的全屏模态列表不是理想的选择。
为了解决此问题,我在我们的自定义MultiSelectComponent中使用了新的CalloutButton组件,可在 DashboardTablet.fxp和CRUDTablet.fxp中找到它们。尽管从名称看来CalloutButton可能是个控件,但它其实是 容器。当按下按钮时,您在CalloutButton的开始和结束标记之间添加的任何内容都会在一个Callout中显示。