要求熟悉 ActionScript、CSS 和 Flex skin。应该在完成本教程之前阅读本系列的第 1 部分。
中级
下载
位置,位置,还是位置。这不仅是房地产商的座右铭,也是 Google、Facebook、Foursquare 等许多 web 先锋的信条,他们都在自己的服务中加入了位置功能。随着移动设备越来越普及,与我们的日常生活密不可分,需要开发包含位置感知、移动功能和地图资产的应用程序,从而向用户提供创新的令人兴奋的新功能。这些新功能会增加开发成本,尤其是对于要开发在所有设备上运行的移动应用程序的开发人员。对于这些开发人员,Flex 和 Flash Platform 让他们能够用单一代码基构建应用程序并把它部署到多种设备上,这有助于降低成本并简化跨平台应用程序的开发。
在本文中,我要介绍如何使用 ArcGIS API for Flex 构建可以部署在 Android 和 Apple iOS 设备上的地图应用程序。本文的示例移动应用程序使用 ArcGIS API for Flex 从 ArcGIS.com 查询美国各州的几何形状信息,当移动设备处于 portrait 状态时显示州名的列表,当移动设备处于 landscape 状态时显示地图并突出显示选择的州。尽管这个应用程序听起来简单,但实际上并不太简单。它会演示 Flex Mobile 框架的一些方面以及如何使用 ArcGIS API for Flex。
下载本教程的示例文件之后,打开 Flash Builder 4.5.1 并执行以下步骤:
可以使用 Android 模拟器或在物理 Android 设备上运行这个应用程序。可以使用 Run Configurations (Run > Run Configuration) 添加一个 Mobile 应用程序并定义 Launch Method(见图 1)。
图 1. 为 MobileApp 设置运行配置
如果打开 MobileApp.mxml,就可以看到主应用程序的源代码。
MobileApp.mxml
<?xml version="1.0" encoding="utf-8"?> <s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" splashScreenImage="@Embed('/assets/Default.png')" firstView="views.QueryView"> </s:ViewNavigatorApplication>
这个应用程序的主类是 ViewNavigatorApplication 的子类。它通过 splashScreenImage
属性在应用程序启动时显示一个嵌入的图像。另外,它把应用程序的第一个视图(见图 2)设置为 QueryView 类的实例。
图 2. 应用程序的第一个视图
第一个视图(即主视图)让用户输入一个 SQL where
子句,这个子句作为从 ArcGIS.com 上的 REST 资源获取美国各州的几何形状信息和名称的查询任务的筛选器。可以在 QueryView.mxml 中找到源代码。
QueryView.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="Query" keyDown="this_keyDownHandler(event)"> <fx:Script> <![CDATA[ private function this_keyDownHandler(event:KeyboardEvent):void { if (event.keyCode === Keyboard.SEARCH) { pushView(); } } private function pushView():void { navigator.pushView(QueryExecuteView, whereInput.text); } ]]> </fx:Script> <s:actionContent> <s:Button icon="@Embed('/assets/search.png')" click="pushView()"/> </s:actionContent> <s:TextInput id="whereInput" width="100%" left="5" right="5" top="10" text="STATE_NAME like 'M%'"/> </s:View>
QueryView 是 View 的子类,它的 title
属性设置为 "Query
"。它垂直地布置子组件。在这里,它只有一个子组件,一个让用户输入 SQL where
子句的 TextInput 实例。在操作内容部分中定义一个 Button 实例(出现在屏幕的右上角),它的 icon
属性引用一个嵌入的放大镜图像,它的单击事件处理函数显示一个 QueryExecuteView 实例,通过 data
属性传递文本输入控件的值。
另外,还有一个按键处理函数,它对按下设备上的硬件搜索按钮做出反应(在 Android 设备上搜索按钮在底部)。它也显示一个 QueryExecuteView 实例。
QueryExecuteView 视图(见图 3)是执行包含用户定义的 where
子句的查询的中间步骤。
图 3. 执行查询
QueryExecuteView.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" xmlns:esri="http://www.esri.com/2008/ags" title="Searching..." viewActivate="queryTask.execute(query)" > <fx:Declarations> <esri:QueryTask id="queryTask" executeComplete="navigator.pushView(QueryResultView, event.featureSet)" showBusyCursor="false" url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" useAMF="true"/> <esri:Query id="query" outFields="['STATE_NAME']" returnGeometry="true" where="{data}"/> </fx:Declarations> <s:BusyIndicator horizontalCenter="0" verticalCenter="0"/> </s:View>
在执行查询时,显示一个忙碌标志,让用户能够看出程序正在做某些事情。这个视图声明一个 QueryTask,把它的 url
属性设置为一个提供美国人口统计数据的 ArcGIS REST 端点。useAMF
属性设置为 true
,表示产生的数据将以二进制 AMF 格式(而不是 JSON 格式)传输回移动设备,这会产生很好的性能并压缩有效负载。另外,这个视图声明一个 Query 实例,把它的 where
属性绑定到视图的 data
属性(这是在前一个视图中在调用 navigator.pushView 时定义的),把返回的字段限制为只包括‘STATE_NAME',通过设置
returnGeometry="true"
要求返回每个州的几何形状信息。在激活视图时,以查询作为参数调用查询任务的 execute
函数。如果执行成功,会显示一个
QueryResultView 视图显示查询的结果。当指示视图导航器把这个类的实例压入视图堆栈的顶时,创建一个实例,用一个 FeatureSet 类实例的引用调用它的 data
设置方法,然后显示这个视图。FeatureSet 有两个属性:
attributes:对象数组,其中的每个对象有一个与
Query 中定义的 outFields 属性内容匹配的键/值对。
geometry
属性。QueryResultsView.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" xmlns:esri="http://www.esri.com/2008/ags" title.landscape="Feature Map" title.portrait="Feature List"> <fx:Script> <![CDATA[ import com.esri.ags.FeatureSet; import mx.collections.ArrayList; import mx.collections.IList; [Bindable] private var listProvider:IList; override public function set data(value:Object):void { super.data = value; const featureSet:FeatureSet = value as FeatureSet; if (featureSet) { listProvider = new ArrayList(featureSet.attributes); } } ]]> </fx:Script> <s:states> <s:State name="portrait"/> <s:State name="landscape"/> </s:states> <s:navigationContent> <s:Button click="navigator.popToFirstView()" icon="@Embed('/assets/home.png')"/> </s:navigationContent> <s:List id="list" left="0" right="0" top="0" bottom="0" dataProvider="{listProvider}" includeIn="portrait" interactionMode="touch" labelField="STATE_NAME"/> <esri:Map id="map" includeIn="landscape" zoomSliderVisible="false"> <esri:extent> <esri:Extent xmin="-137.6" ymin="19.8" xmax="-50.7" ymax="52.9"/> </esri:extent> <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/> <esri:GraphicsLayer graphicProvider="{data.features}"> <esri:symbol> <esri:SimpleFillSymbol alpha="0.5" color="red"> <esri:outline> <esri:SimpleLineSymbol alpha="1.0" color="yellow"/> </esri:outline> </esri:SimpleFillSymbol> </esri:symbol> </esri:GraphicsLayer> </esri:Map> </s:View>
视图可以处于两种状态之一:portait 或 landscape。视图的状态由用户拿着设备的方式控制。Flex 移动框架会监视设备的方向并相应地设置视图的状态。这种状态管理机制让您能够根据方向显示查询任务特性。当处于 portrait
状态时,应用程序的标题设置为 Feature List,一个 List 实例填充此视图(见图 4)。列表中的每一行显示一个特性的 STATE_NAME
属性值。
图 4. 处于 portrait 模式的应用程序
当处于 landscape
状态时,列表被替换为一个 Map 实例,它显示包含 48 个州的地理区域。这个地图由两层组成。第一层采用平铺方式,把从提供的 URL 获取的形状平铺在一起。第二层是一个 GraphicsLayer 实例,它的数据提供者是 data
属性中提供的特性。使用一个 SimpleFillSymbol 实例在图形层中把每个特性或图形符号化(突出显示),它用半透明的红色填充每个州并把轮廓设置为黄色实线(见图 5)。为了让用户能够导航回主屏幕,在导航内容区域(左上角)中添加一个按钮,它的图标引用一个房屋图像,单击事件处理函数指示导航器返回到第一个视图(在这里是 QueryView)。
图 5. 处于 landscape 模式的应用程序
在 FlashBuilder 4.5.1 中,现在可以把项目从 IDE 直接导出到 Android 设备、BlackBerry Tablet OS 设备和 iOS 设备。
首先,选择 Project > Export Release Version 并完成打包过程(见图 6)。
图 6. 导出发布版
如果希望部署到 iOS 设备(见图 7),您必须作为开发人员与 Apple 签约,然后把一个 Provisioning Profile 文件下载到本地计算机上。生成 IPA 文件之后(这要花一段时间),把发布文件夹中的 IPA 文件放到 iTunes 中,同步自己的 iPhone 以传输应用程序。
图 7. 针对 iOS 设备导出发布版
本文只涉及到了使用 ArcGIS API for Flex 开发移动应用程序的皮毛。更多信息参见: