目录
- 第1部分:创建基本的移动应用程序
- 第2部分:使用移动项渲染器
- 第3部分:在视图之间导航
- 第4部分:创建操作栏
- 第5部分:集成设备功能
- 第6部分:使用RemoteObject
- 第7部分:使用本地SQLite数据库
- 第8部分:导航组织结构图
要求
预备知识
了解 Flex SDK“Hero”和Flash Builder“Burrito”。
其他要求
Flash Builder“Burrito”(包括Adobe Flex SDK“Hero”预览版)
下载示例文件并将该文件解压到您的文件系统上。
用户水平
初级
示例文件
- flex_android_workshop.zip
在本教程中,使用Flash Builder“Burrito”和Flex SDK“Hero”,为Android设备构建一个简单但功能全面的员工通讯薄应用程序。“Burrito”是下一个Flash Builder版本的代号,“Hero”是下一个Flex SDK版本的代号。
完成本教程不需要Android设备。可以使用Flash Builder“Burrito”中提供的简单的模拟器来运行和调试应用程序。
Employee Directory应用程序允许您:
- 搜索员工
- 查看员工详细信息
- 在组织结构图中上下导航
- 呼叫员工,向其发送文本和电子邮件
第1部分:创建基本的移动应用程序
在本节中,构建一个简单的移动应用程序,它显示员工列表。
步骤1:创建Flex Mobile项目
- 在Flash Builder菜单中选择File > New > Flex Mobile Project。
- 在Project Location选项卡上,指定EmployeeDirectory作为项目名称并单击Next(参见图1)。

图1.?指定EmployeeDirectory作为项目名称。
- 在Mobile Settings选项卡上,保留默认值并单击Finish(参见图2)。

图2.?Mobile Settings选项卡
- 从您刚才解压的FlexAndroidWorkshop文件夹复制assets目录并将其粘贴到EmployeeDirectory项目的src目录下。
步骤2:编写应用程序
- 打开EmployeeDirectory.mxml:
- 请注意根节点:MobileApplication
- 请注意MobileApplication的firstView特性引用了EmployeeDirectoryHome
- 打开EmployeeDirectoryHome.mxml并按如下形式实现View:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Home"
creationComplete="srv.send()">
<fx:Declarations>
<s:HTTPService id="srv" url="assets/employees.xml"/>
</fx:Declarations>
<s:List id="list" top="0" bottom="0" left="0" right="0"
dataProvider="{srv.lastResult.list.employee}"
labelField="lastName"/>
</s:View>
注意:
- 确保在EmployeeDirectoryHome.mxml中实现此代码,而不是在EmployeeDirectory.mxml中。
- 不要忘记将creationComplete事件添加到视图中
步骤3:运行应用程序
- 右键单击EmployeeDirectory.mxml中的任何地方并选择Run AS > Mobile Application。
- 选择On desktop并选择一个要模拟的设备。例如Google Nexus One(参见图3)。

图3.?选择要模拟的设备。
- 单击Run测试应用程序。应用程序应该类似于图4:

图4.?应用程序应该类似于本图。
?
第2部分:使用移动项渲染器
在本节中,为员工列表定义一个移动项渲染器。
步骤
- 打开EmployeeDirectoryHome.mxml并为List定义一个内联的itemRenderer。项渲染器在第一行显示员工的姓名,在第二行显示员工的职位。
<s:List id="list" top="0" bottom="0" left="0" right="0"
dataProvider="{srv.lastResult.list.employee}">
<s:itemRenderer>
<fx:Component>
<s:MobileIconItemRenderer
label="{data.firstName} {data.lastName}"
messageField="title"/>
</fx:Component>
</s:itemRenderer>
</s:List>
- 运行并测试应用程序。应用程序应该类似于图5:

图5.?应用程序应该类似于本图。
第3部分:在视图之间导航
在本节中,创建一个EmployeeDetails视图,它显示在列表中选择的员工的详细信息。您将学习如何在视图之间导航和传递信息。
步骤1:创建EmployeeDetails视图
- 右键单击EmployeeDirectory中的views文件夹并选择New > MXML Component。指定EmployeeDetails作为组件名称并单击Finish(参见图6)。

图6.?指定EmployeeDetails作为组件名称。
- 按如下方式实现EmployeeDetails:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="Employee Details">
<s:HGroup verticalAlign="middle">
<s:Image source="assets/pics/{data.picture}"/>
<s:VGroup>
<s:Label text="{data.firstName} {data.lastName}"/>
<s:Label text="{data.title}"/>
<s:Label text="{data.department}"/>
<s:Label text="{data.city}"/>
</s:VGroup>
</s:HGroup>
步骤2:打开详细信息视图
- 打开EmployeeDirectoryHome.mxml并为List提供一个更改处理函数,用于打开选定员工的详细信息视图:
<s:List id="list" top="0" bottom="0" left="0" right="0"
dataProvider="{srv.lastResult.list.employee}"
change="navigator.pushView(EmployeeDetails,list.selectedItem)">
<s:itemRenderer>
<fx:Component>
<s:MobileIconItemRenderer
label="{data.firstName} {data.lastName}"
messageField="title"/>
</fx:Component>
</s:itemRenderer>
</s:List>
步骤3:运行应用程序
- 在列表中选择一名员工。应该会显示选定员工的员工详细信息视图(参见图7)。

图7.?显示了选定员工的员工详细信息视图。
第4部分:创建操作栏
在本节中,为Employee Directory提供一个操作栏:
- 为应用程序中的所有视图提供一个Home按钮,用户可以单击它返回到应用程序的第一个视图。
- 为EmployeeDirectoryHome的操作栏提供搜索控件来搜索员工。
步骤1:创建Home按钮
- 打开EmployeeDirectory.mxml并定义以下导航栏内容(在结束标记之前):
<s:navigationContent>
<s:Button icon="@Embed('assets/home.png')" click="navigator.popToFirstView()"/>
</s:navigationContent>
- 运行并测试应用程序。请注意,由于导航控件是在应用程序级别定义的,所以它将在应用程序的所有视图之间共享(参见图8)。

图8.?导航控件在应用程序的所有视图之间共享。
步骤2:创建搜索栏
- 打开EmployeeDirectoryHome.mxml。
- 添加以下titleContent和actionContent(在结束</fx:Declarations>标记之后),创建一个搜索栏:
<s:titleContent>
<s:TextInput id="key" width="100%"/>
</s:titleContent>
<s:actionContent>
<s:Button icon="@Embed('assets/search.png')" click="srv.send()"/>
</s:actionContent>
对于这个初始实现,单击搜索按钮将返回所有员工,无论您在搜索字段中键入了什么内容。您将在第6部分实现有效的搜索功能。
- 因为我们现在在用户单击Search按钮时将发送数据请求,所以删除在视图上定义的creationComplete处理函数。
- 运行并测试应用程序。
请注意,EmployeeDetails和EmployeeDirectoryHome视图都继承自在EmployeeDirectory.mxml中定义的Home按钮。尽管让应用程序的所有视图都有一个Home按钮通常是个不错的注意,但如果应用程序的Home视图上有一个Home按钮,则显得多余(而且可能引起混淆)(参见图9)。

图9.?EmployeeDetails和EmployeeDirectoryHome视图都继承自在EmployeeDirectory.mxml中定义的Home按钮。
步骤3:删除EmployeeDirectoryHome中的Home按钮
- 打开EmployeeDirectoryHome.mxml并在<s:titleContent>标记之前添加一个空的navigatonContent标记:
<s:navigationContent/>
- 运行并测试应用程序(参见图10)。

图10.?删除Home按钮
请注意,当打开一位员工的详细信息视图,然后使用您设备的后退按钮(或应用程序的Home按钮)返回到列表时,列表是空的。这是因为在一个视图激活时,以前激活的视图会自动销毁。当单击后退按钮时,以前的视图实际上将被重新实例化。
步骤4:持久保存搜索结果
尽管当视图在不活动时会被销毁,但它的“data”特性会被持久保存并在重新实例化该视图时重新分配。
利用data特性持久保存搜索结果:
- 将一个结果事件处理函数添加到HTTPService,在该处理函数中将HTTP服务调用的lastResult分配给视图的data特性。
<s:HTTPService id="srv" url="assets/employees.xml" result="data=srv.lastResult.list.employee"/>
- 将List绑定到视图的data特性。
<s:List id="list" top="0" bottom="0" left="0" right="0"
dataProvider="{data}"
change="navigator.pushView(EmployeeDetails,list.selectedItem)">
<s:itemRenderer>
<fx:Component>
<s:MobileIconItemRenderer
label="{data.firstName} {data.lastName}"
messageField="title"/>
</fx:Component>
</s:itemRenderer>
</s:List>
- 运行并测试应用程序。
第5部分:集成设备功能
在本节中,使用户能够在应用程序内呼叫一位员工,向其发送文本或电子邮件。
步骤1:显示操作列表
- 在EmployeeDetails.mxml中,在<s:HGoup>开始标记之前添加一个<fx:Script>块。
<fx:Script>
<![CDATA[ ]]>
</fx:Script>
- 在新<fx:Script>块内,定义一个可绑定的ArrayCollection来持有针对所选定员工的可用操作列表:
[Bindable]
protected var actions:ArrayCollection;
请注意:确保导入了ArrayCollection类,此代码才能编译:
import mx.collections.ArrayCollection;
- 定义以下嵌入式图标。您将在操作列表itemRenderer中使用它们。
[Embed("assets/sms.png")]
private var smsIcon:Class;
[Embed("assets/phone.png")]
private var phoneIcon:Class;
[Embed("assets/mail.png")]
private var mailIcon:Class;
- 改写视图的“data”特性的setter方法,基于可用数据向操作列表填充可用于该员工的操作。例如,只有在手机号码可用时,才应向用户显示“SMS”操作。
override public function set data(value:Object):void
{
super.data = value;
actions = new ArrayCollection();
if (data.officePhone)
{
actions.addItem({type: "tel",name: "Call office",details: data.officePhone,icon:phoneIcon});
}
if (data.cellPhone)
{
actions.addItem({type: "tel",name: "Call mobile",details: data.cellPhone,icon:phoneIcon});
actions.addItem({type: "sms",name: "SMS",icon:smsIcon});
}
if (data.email)
{
actions.addItem({type: "mailto",name: "Email",details: data.email,icon:mailIcon});
}
}
- 显示操作列表:在结束</s:HGroup>标记下,添加一个绑定到操作列表的List组件。
<s:List id="list" dataProvider="{actions}"
top="160" left="0" right="0" bottom="0">
<s:itemRenderer>
<fx:Component>
<s:MobileIconItemRenderer
paddingTop="8" paddingBottom="8" verticalGap="6"
labelField="name"
messageField="details"
decoratorClass="{data.icon}"/>
</fx:Component>
</s:itemRenderer>
</s:List>
- 运行并测试应用程序
当在列表中选择一位员工时,应该看到针对该员工的可用操作列表(参见图11)。这些操作目前是无效的。在下一步中将使它们生效。

图11.?针对该员工的可用操作列表。
步骤2:触发操作
- 向List添加更改处理函数:
<s:List id="list" dataProvider="{actions}"
top="160" left="0" right="0" bottom="0"
change="list_changeHandler(event)">
<s:itemRenderer>
<fx:Component>
<s:MobileIconItemRenderer
paddingTop="8" paddingBottom="8" verticalGap="6"
labelField="name"
messageField="details"
decoratorClass="{data.icon}"/>
</fx:Component>
</s:itemRenderer>
</s:List>
- 按如下方式实现list_changeHandler:
protected function list_changeHandler(event:IndexChangeEvent):void
{
var action:Object = list.selectedItem;
switch (action.type)
{
case "tel":
navigateToURL(new URLRequest("tel:"+action.details));
break;
case "sms":
navigateToURL(new URLRequest("sms:"+action.details));
break;
case "mailto":
navigateToURL(new URLRequest("mailto:"+action.details));
break;
}
}
请注意:确保导入了spark.events.IndexChangeEvent(而不是mx.events.IndexChangedEvent),此代码才能编译:
import spark.events.IndexChangeEvent;
- 运行并测试应用程序。
?
第6部分:使用RemoteObject
在本节中,实现搜索功能。将HTTPService替换为一个RemoteObject,后者提供了一个findByName方法。为方便起见,RemoteObject已在云中托管,您无需在您自己的基础设施中部署任何内容。
当然您可以使用HTTPService实现搜索功能。我们采用RemoteObject是为了试验不同的数据访问战略。
如果对使用RemoteObject不感兴趣,可以直接跳到第7部分。
步骤
- 打开EmployeeDirectoryHome.mxml。将HTTPService替换为所定义的RemoteObject,如下所示:
<s:RemoteObject id="srv" destination="employeeService" endpoint="http://flex.org:8080/extras/messagebroker/amf" result="data=srv.findByName.lastResult"/>
- 修改搜索按钮的单击处理函数:使用RemoteObject的findByName的方法,查找与用户输入的搜索关键词相匹配的员工。
<s:Button icon="@Embed('assets/search.png')" click="srv.findByName(key.text)"/>
- 运行并测试应用程序:在搜索字段中键入几个字符并单击搜索按钮,查看匹配员工的列表(参见图12)。

图12.?在搜索字段中键入一些字符并单击搜索按钮,查看匹配员工的列表。
?
第7部分:使用本地SQLite数据库
在本节中,更改应用程序的数据访问逻辑:不使用RemoteObject(或HTTPService),使用您设备上可用的SQLite数据库来访问数据。
步骤
- 复制FlexAndroidWorkshop文件夹中的model目录并将其粘贴到EmployeeDirectory项目的src目录下。
- 浏览EmployeeDAO和Employee类的源代码:
- EmployeeDAO类提供了数据访问对象模式的一种基本实现:它封装了用于创建、更新和删除员工的数据访问逻辑。如果数据库中不存在员工表,EmployeeDAO还将包含某种逻辑来创建它并使用示例数据填充它。
- Employee是一个基本值对象,它还提供了某种延迟加载逻辑来加载员工的经理并根据需要发送报告。
- 在EmployeeDirectoryHome.mxml中,将RemoteObject(或者如果您没有完成第6部分,则为HTTPService)替换为一个EmployeeDAO实例。
<model:EmployeeDAO id="srv"/>
请注意:确保将model命名空间绑定到了mxml文档顶部的View定义中:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Home" xmlns:model="model.*">
- 相应地,修改搜索按钮单击事件处理函数。
<s:Button icon="@Embed('assets/search.png')" click="data=srv.findByName(key.text)"/>
请注意,在本例中,我们可以直接将findByName函数的返回值分配给data,因为EmployeeDAO使用了数据库访问API的同步版本。
- 运行并测试应用程序。
第8部分:导航组织结构图
在本节中,向Employee Details视图添加“View manager”和“View direct reports”操作,使用户能够在组织结构图中上下导航。
步骤1:创建DirectReports视图
- 右键单击EmployeeDirectory项目中的views文件夹并选择New > MXML Component。指定DirectReports作为组件名称并单击Finish(参见图13)。

图13.?指定DirectReports作为组件名称。
- 按如下方式实现DirectReports.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Direct Reports">
<s:List id="list" top="0" bottom="0" left="0" right="0"
dataProvider="{data.directReports}"
change="navigator.pushView(EmployeeDetails,list.selectedItem)">
<s:itemRenderer>
<fx:Component>
<s:MobileIconItemRenderer
label="{data.firstName} {data.lastName}"
messageField="title"/>
</fx:Component>
</s:itemRenderer>
</s:List>
</s:View>
步骤2:添加操作来导航组织结构图
- 在EmployeeDetails.mxml中,向set data函数添加两个可能的操作:
if (data.manager)
{
actions.addItem({type: "employee",name: "View manager",details: data.manager.firstName + " " + data.manager.lastName,employee: data.manager});
}
if (data.directReports && data.directReports.length > 0)
{
actions.addItem({type: "reports",name: "View direct reports",details: "(" + data.directReports.length + ")",employee: data});
}
- 在List更改处理函数中,添加两个case语句来触发相应的操作:
case "employee":
navigator.pushView(EmployeeDetails,action.employee);
break;
case "reports":
navigator.pushView(DirectReports,action.employee);
break;
步骤3:运行应用程序
- 选择一位拥有经理的员工(参见图14)。

图14.?选择一位拥有经理的员工。
- 单击“View manager”操作(参见图15)。

图15.?单击“View manager”。
- 选择一位拥有直接报告的员工并单击“View direct reports”操作(参见图16)。

图16.?Direct Reports
延伸阅读
您在为Android开发应用程序期间将发现下面一些资源很有用:
- Adobe Flex SDK“Hero”简介
- Flash Builder“Burrito”中的新特性
- Flex Test Drive for Mobile
- 使用Flex SDK“Hero”和Flash Builder“Burrito”进行移动开发
- Flex SDK“Hero”示例应用程序和教程
- Flex Developer Center
- Mobile and Devices Developer Center

+

本文在Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License授权下提供。超出本许可证范围且与本文中包含的示例代码相关的权限可在Adobe上找到。
更多相关链接
- 使用Flex SDK“Hero”和Flash Builder“Burrito”进行移动开发
教程和示例
教程
- 使用Flash Builder“Burrito”和Flex SDK“Hero”创建Android移动应用程序
- 使用Flex向您的ColdFusion应用程序添加实时数据可视化
- 迁移到Flex 4:使用皮肤
示例
- Adobe Flex SDK“Hero”和Flash Builder“Burrito”示例
- DigiPri构件销售仪表板 – 第1部分:概述
- DigiPri构件销售仪表板 – 第2部分:安装服务器应用程序