Posts Tagged "Flex"

关于Flex端实时更新的一些方法总结

诚为大家所知,Flash之所以优秀,就是它可以带来良好的用户体验和交互特性。既然涉及到交互性,开发人员在开发过程中必然会遇到实时更新的问题,那么,当后台数据发现变化的时候,如何让Flash端实时刷新显示数据呢?以下是一些可资参考的方法,各种方案优缺点各异,开发系统之前请仔细考量:

第一种:Flex端采用轮询的方式访问后台,查看后台数据是否有更新,若有则获取数据,更新界面信息;这中方法一般适用于后台更新并不频繁,对实时性信息更新要求程度一般的实时更新。例如QQ上的好友个人头像更新。

第二种:Socket :这种方法的原理是后台携带数据并发出数据更新通知,前台监听到通知后得到数据发布到界面上。此方式适用于对信息的及时性特别强的业务。如聊天室,IM即时聊天!这方面flash已有成熟的方案:Red5或FMS

第三种:使用 BlazeDS 的 Romoting 消息服务,例如商城购物车监控。具体优劣待查。

第四种:RTMP方式:Adobe在2009年一月开始将RTMP进行开源。不过应用的时候还是需要向Adobe进行License申请,详情:http://www.adobe.com/aboutadobe/pressroom/pressreleases/200901/012009RTMP.html

 

Flex框架之Cairngorm

一.简介

Cairngorm是Abode推出的Flex RIAs框架,其实是MVC的发扬光大,它由七大部分组成。

  1. Model(数据模型M):使用singleton(单例)模式共享变量;
  2. VO( Value Object):储存特定值对象变量。
  3. VIew(视图V):将Model的数据绑定互组件并广播侦听Cairngorm Event;
  4. Controller(控制器):侦听Cairngorm事件并将其映射到Cairngorm Command;
  5. Command(命令):调用Cairngorm Delegate或其它Command ,并更新Model;
  6. Delegate(委托):实例化RPC(远程过程调用)并将其结果返回给Command;
  7. Business(业务):定义RPC。
 

最简单易理解的Flex PureMVC入门例子:实现登录

2010/1/14日更新
加入官方一个Demo:Demo_AS3_Flex_CafeTownsend.zip (162)

_____________________________华丽的分割线________________________________

PureMVC 学习笔记(一)中介绍了一个《flex框架pureMVC的使用:第一步》(后简称:第一步)的例子,此文关于PureMVC的介绍非常生动明了,如果想快速学习PureMVC这个framework的话,建议看一下。

不过其中所举例子对于想要自己动手使用PureMVC的人就稍显不足了。因为《第一步》对于代码的介绍是从application启动加载Facade开始的,然后注册Command,Proxy,Mediator,这样的说明的好处是快速让读者理解PureMVC内部运行机制。在理解了PureMVC的原理之后,我们就要开始构思怎样对一个工程应用PureMVC,谨以一个登录的例子,说明如何使用PureMVC构建工程,工程结构图如下:

2009-09-04_112259

因为所有的 Mediator、Proxy、Command、Event 的名称都被我定义在system包下的NameSpace.as中,所以先看给出此as的代码:

package system
{

 public class NameSpace
 {
  public static const LoginProxyName:String=”LoginProxy”;
  public static const LoginSuccess:String=”loginSuccess”;
  public static const LoginFailed:String=”loginFailed”;
  public static const LoginEvent:String=”loginEvent”;
  public static const LoginMediatorName:String=”loginMediator”;
  public static const ApplicationLogin:String=”login”;
  public static const ApplicationMediatorName:String=”appliactionMediator”;
  public static const FacadeStart:String=”start”;
 }
}

Model和Proxy

因为数据来自Model层,我们用Proxy进行管理,所以我们先来设计这一模块,定义LoginVO这样一个简单的数据结构,用于存储登录的数据:用户名和密码。代码如下:

package model.vo
{
 public class LoginVO
 {
  public var username:String;
  public var password:String;
 }
}

 接着建立LoginProxy,需要继承Proxy实现IProxy:

package model
{
 import model.vo.LoginVO;
 import org.puremvc.as3.interfaces.IProxy;
 import org.puremvc.as3.patterns.proxy.Proxy;
 import system.NameSpace;

 public class LoginProxy extends Proxy implements IProxy
 {
  public function LoginProxy()
  {
   super(NameSpace.LoginProxyName);
  }

  public function CheckLogin(vo:LoginVO):void
  {
   if (vo.username == “test” && vo.password == “test”)
   {
    sendNotification(NameSpace.LoginSuccess, vo);
   }
   else
   {
    sendNotification(NameSpace.LoginFailed);
   }
  }
 }
}

每一个Proxy都需要有自己的名称,为了便于统一的管理,我把所有的Name都定义在NameSpace中,这样做的好处是有利于协作开发,同时也有助于程式的调试。从代码中可以看到,整个Model与外界没什么联系,提供了一个CheckLogin()方法,根据判断的结果发送通知。至于这样的通知发送出去谁来处理,怎么处理,就不是Proxy关心的事了。由此可知,Proxy的耦合度相当低!(感觉PureMVC这个组织里,Facade是老大,管着手下三个小弟:Proxy、Mediator、Command,这三个家伙都是各干各的,从不互相帮助,各人自扫门前雪,真是selfish)

View 和 Mediator

任何一个应用都有和用户交互的界面,将这些界面统一起来进行管理,就是PureMVC的View层。在View层内,实现界面的管理委托给了Mediator,Mediator负责管理应用界面的数据更新和提交数据。当用户界面发生数据更新或用户操作时,界面通过事件通知管理它的Mediator,然后Mediator会根据情况发送通知给系统。先建议一个登录的界面:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Panel xmlns:mx=”http://www.adobe.com/2006/mxml
    fontSize=”12″
    layout=”vertical”
    horizontalAlign=”center”
    title=”用户登录”
    width=”314″>
 <mx:Script>
  <![CDATA[
   import system.NameSpace;
  ]]>
 </mx:Script>
 <mx:Form width=”100%”
    height=”100%”>
  <mx:FormHeading label=”敬请登录”/>
  <mx:FormItem label=”登录名称”>
   <mx:TextInput id=”loginName”/>
  </mx:FormItem>
  <mx:FormItem label=”登录密码”>
   <mx:TextInput id=”loginPassword”/>
  </mx:FormItem>
  <mx:FormItem>
   <mx:Button label=”确定”
        id=”loginBtn”
        click=”dispatchEvent(new Event(NameSpace.LoginEvent))”/>
  </mx:FormItem>
 </mx:Form>
 <mx:Label id=”labStatus”/>
</mx:Panel>

基于这个界面,定义两个Mediator:一个是LoginMediator,负责管理登录对话框和登录的操作;另一个是ApplicationMediator,用来负责管理登录成功后的界面。先看LoginMediator:

package view
{
 import flash.events.Event;

 import model.vo.LoginVO;

 import mx.managers.PopUpManager;

 import org.puremvc.as3.interfaces.IMediator;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.mediator.Mediator;

 import system.NameSpace;

 public class LoginMediator extends Mediator implements IMediator
 {
  //获取应用实例
  private var loginPanel:LoginForm;
  private var loginApplication:PureLoginMVC;

  public function LoginMediator(app:Object)
  {
   super(NameSpace.LoginMediatorName, app);
   loginApplication=app as PureLoginMVC;
   loginPanel=new LoginForm();
   loginPanel.addEventListener(NameSpace.LoginEvent, onLogin);
   PopUpManager.addPopUp(loginPanel, loginApplication);
   PopUpManager.centerPopUp(loginPanel);
  }

  //监听通知
  override public function listNotificationInterests():Array
  {
   var arr:Array=new Array();
   arr.push(NameSpace.LoginSuccess);
   arr.push(NameSpace.LoginFailed);
   return arr;
  }

  //响应通知
  override public function handleNotification(notification:INotification):void
  {
   switch (notification.getName())
   {
    case NameSpace.LoginSuccess:
     setLoginSuc();
     break;
    case NameSpace.LoginFailed:
     setLoginFailed();
     break;
    default:
     break;
   }
  }

  //登录成功,移除登录窗口
  private function setLoginSuc():void
  {
   PopUpManager.removePopUp(loginPanel);
  }

  //登录失败,提示
  private function setLoginFailed():void
  {
   loginPanel.labStatus.text=”用户名密码有误,请重试”;
   loginPanel.loginName.setFocus();
  }

  private function onLogin(evt:Event):void
  {
   if (loginPanel.loginName.text != “” && loginPanel.loginPassword.text != “”)
   {
    var loginVO:LoginVO=new LoginVO();
    loginVO.username=loginPanel.loginName.text;
    loginVO.password=loginPanel.loginPassword.text;
    sendNotification(NameSpace.ApplicationLogin, loginVO);
   }
   else
   {
    loginPanel.labStatus.text=”请输入用户名和密码”;
   }
  }

 }
}

同样,LoginMediator 的名称来自于 NameSpace.as ,继承Mediator实现IMediator,LoginMediator 注册监听了两个事件:登录成功和失败,并做了对应的响应处理。其中onLogin()方法在收集了登录信息后,发出通知。另外还有一个ApplicationMediator:

package view
{
 import model.vo.LoginVO;

 import mx.controls.Label;

 import org.puremvc.as3.interfaces.IMediator;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.mediator.Mediator;

 import system.NameSpace;

 public class ApplicationMediator extends Mediator implements IMediator
 {
  private var loginApplication:PureLoginMVC;

  //构造器,获取application实例
  public function ApplicationMediator(app:Object)
  {
   super(NameSpace.ApplicationMediatorName, app);
   loginApplication=app as PureLoginMVC;
  }

  //监听通知
  override public function listNotificationInterests():Array
  {
   return [NameSpace.LoginSuccess];
  }

  //响应通知
  override public function handleNotification(notification:INotification):void
  {
   switch (notification.getName())
   {
    case NameSpace.LoginSuccess:
     setLoginSuc(notification.getBody() as LoginVO);
     break;
    default:
     break;
   }
  }

  private function setLoginSuc(loginVO:LoginVO):void
  {
   var label:Label=new Label();
   label.text=”欢迎光临!” + loginVO.username;
   loginApplication.addChild(label);
  }

 }
}

这个mediator只监听了登录成功的通知,并响应更新主应用上的数据。

Controller 和 Command

Controller和Command看起来像一条纽带,联系这Mediator和Proxy.它处理Mediator发送的通知并调用Proxy中的public 方法来处理. Command需要继承SimpleCommand或MocroCommand并实现ICommand.分析系统,需要在Command中注册Proxy和Mediator,以及一个处理Login的。这里的设计思路为:ModelCommand(用于注册Proxy)、ViewCommand(注册Mediator)、ApplicationCommand(用于系统启动时,集成ModelCommand和ViewCommand)、LoginCommand(用于接收登录通知并调用Proxy实现登录)。先看ModelCommand:

package Controller
{
 import model.LoginProxy;

 import org.puremvc.as3.interfaces.ICommand;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.command.SimpleCommand;

 public class ModelCommand extends SimpleCommand implements ICommand
 {
  public function ModelCommand()
  {
   super();
  }

  override public function execute(notification:INotification):void
  {
   facade.registerProxy(new LoginProxy());
  }

 }
}

接着写ViewCommand:

package Controller
{
 import org.puremvc.as3.interfaces.ICommand;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.command.SimpleCommand;

 import view.ApplicationMediator;
 import view.LoginMediator;

 public class ViewCommand extends SimpleCommand implements ICommand
 {
  public function ViewCommand()
  {
   super();
  }

  //注册Mediator
  override public function execute(notification:INotification):void
  {
   var app:PureLoginMVC=notification.getBody() as PureLoginMVC;
   facade.registerMediator(new ApplicationMediator(app));
   facade.registerMediator(new LoginMediator(app));
  }

 }
}

在ApplicationCommand中集成注册上面两个Command:

package Controller
{
 import org.puremvc.as3.interfaces.ICommand;
 import org.puremvc.as3.patterns.command.MacroCommand;

 public class ApplicationCommand extends MacroCommand implements ICommand
 {
  //构造器,可写可不写
  public function ApplicationCommand()
  {
   super();
  }

  //写法一
  override protected function initializeMacroCommand():void
  {
   addSubCommand(ModelCommand);
   addSubCommand(ViewCommand);
  }

 }
}

处理登录通知的LoginCommand:

package Controller
{
 import model.LoginProxy;
 import model.vo.LoginVO;

 import org.puremvc.as3.interfaces.ICommand;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.command.SimpleCommand;

 import system.NameSpace;

 public class LoginCommand extends SimpleCommand implements ICommand
 {
  public function LoginCommand()
  {
   super();
  }

  override public function execute(notification:INotification):void
  {
   var loginVO:LoginVO=notification.getBody() as LoginVO;
   //var loginProxy:LoginProxy = new LoginProxy();
   //从facade中获取proxy
   var loginProxy:LoginProxy=facade.retrieveProxy(NameSpace.LoginProxyName) as LoginProxy;
   loginProxy.CheckLogin(loginVO);
  }

 }
}

完成了这些之后,就到了 PureMVC 的核心:Facade,通过它,Mediator,Proxy,Command才能很好的结合在一起。这里将它命名为MyFacade,代码如下:

package view
{
 import model.vo.LoginVO;

 import mx.controls.Label;

 import org.puremvc.as3.interfaces.IMediator;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.mediator.Mediator;

 import system.NameSpace;

 public class ApplicationMediator extends Mediator implements IMediator
 {
  private var loginApplication:PureLoginMVC;

  //构造器,获取application实例
  public function ApplicationMediator(app:Object)
  {
   super(NameSpace.ApplicationMediatorName, app);
   loginApplication=app as PureLoginMVC;
  }

  //监听通知
  override public function listNotificationInterests():Array
  {
   return [NameSpace.LoginSuccess];
  }

  //响应通知
  override public function handleNotification(notification:INotification):void
  {
   switch (notification.getName())
   {
    case NameSpace.LoginSuccess:
     setLoginSuc(notification.getBody() as LoginVO);
     break;
    default:
     break;
   }
  }

  private function setLoginSuc(loginVO:LoginVO):void
  {
   var label:Label=new Label();
   label.text=”欢迎光临!” + loginVO.username;
   loginApplication.addChild(label);
  }

 }
}

 最后,在主应用中单例调用MyFacade的实例:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application fontSize=”12″
    xmlns:mx=”http://www.adobe.com/2006/mxml
    creationComplete=”init()”
    layout=”absolute”>
 <mx:Script>
  <![CDATA[
   import system.MyFacade;
   import org.puremvc.as3.patterns.facade.Facade;

   public function init():void
   {
    var myFacade:MyFacade=MyFacade.getInstance();
    myFacade.startup(this);
   }
  ]]>
 </mx:Script>
</mx:Application>

到此为止,一个PureMVC构建的登录例子就完成了,呵呵,希望能达到一看就懂的效果~

源码下载:PureMVCLogin.rar (572)

 

美丽是一门技艺—-Flex CSS

对于Flex CSS,Adobe推荐使用CamelCase格式命名选择器和样式属性。例如
.mystyle
{
    font:Arial;
    fontStyle:italic;
}
ComboBox
{
    Selection-color:#32cd32
}

关于CamelCase:
  也译作“骆驼拼写法”。CamelCase在英语中,是指通过单词起首大写方式进行复合词拼写的方法。该拼写方法使得复合词连续没有空格,但组成复合词的每个子单词起首字母大写,由此易于分辨复合词的组成.

Flex常用的CSS选择器

一、Class选择器

Class选择器名称由”.”起始,接以选择器名称。通过将组件的styleName属性设置为选择器名称,Class选择器定义的样式将被显式地指定给要修饰的组件。

二、Type选择器

Type选择器为指定类型的组件应用其定义的样式。Type选择器的名称为某类组件类型,如Button、ComboBox等

三、Application选择器

Application选择器是典型的Type选择器,只不过由于Application容器的特殊而显得不同。作为Flex应用的顶级容器,以及容器子项继承样式的能力,开发者可以创建Application选择器样式,由此设定整个应用的标准外观属性。

但另一方面,我们可以设定的外观属性仅仅局限在那些特殊可继承的样式属性,对于那些不可继承的样式属性,即使在Application选择器样式中进行定义,也无法应用到整个应用中。

四、global选择器

使用global选择器,能够为那些不可继承的样式属性设定全局统一应用的样式。global选择器不同于Type选择器,并没有一个global类。也不同于Class选择器,开发者无需显式的设定组件的styleName属性为global.在global选择器中定义的样式,会自动应用到全局应用中。

CSS 優先級

自己画了个图,表述一下样式应用的优先级:

2009-08-26_162556

 

Flex 构建 WebService 应用—-天气预报为例

最近做公司的一个项目,需要与公司别的部门进行资料串联。商量之后,选择的方式非侵入式的资料串联方式(何谓侵入式资料串联?比如说直接连接别人的 DB 读取资料,众所周知,这是不可取的。)。具体的,就是对方生成 WebService,然后我这边通过WebService抓取所需资讯。

今天对方把WebService生成好了,然后请我们测试抓取资料是否OK,测试的例子因为涉及公司的机密,在这里该成天气预报的例子写下来:

如果你是一个学习Flex的新人,那么请先安装Flex Builder3或者给Eclipse安装Flex的插件。这个例子中我们采用国家气象局提供的WebService来查询天气预报,WebService地址如下:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl。你可以在浏览器中打开这个地址,从中可以看到这么一段xml:

  • - <s:element name=”getWeatherbyCityName”>
  • - <s:complexType>
  • - <s:sequence>
  • <s:element minOccurs=”0″ maxOccurs=”1″ name=”theCityName” type=”s:string” />
  • </s:sequence>
  • </s:complexType>
  • </s:element>
  • - <s:element name=”getWeatherbyCityNameResponse”>
  • - <s:complexType>
  • - <s:sequence>
  • <s:element minOccurs=”0″ maxOccurs=”1″ name=”getWeatherbyCityNameResult” type=”tns:ArrayOfString” />
  • </s:sequence>
  • </s:complexType>
  • </s:element>

其中getWeatherbyCityName就是请求WS返回特定城市天气预报的函数名称,而theCityName就是城市名的参数(其实这个参数你只 要将合法的城市名以String格式传给getWeatherbyCityName就可以了。getWeatherbyCityNameResponse表述的是它的返回值,并且返回值类型为:ArrayOfString.因此在Flex程序用ArrayColection来接收返回值.

编写程序如下:

  •   <?xml version=”1.0″ encoding=”utf-8″?>
    <mx:Application xmlns:mx=”
    http://www.adobe.com/2006/mxml” fontSize=”13″
         layout=”absolute” horizontalAlign=”center”>
        <mx:Style source=”/style/style.css”/>
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;
            function onload(event:ResultEvent):void{
                resetWeather();
                var weatherInfo:ArrayCollection = (event.result) as ArrayCollection;
                for(var i:int=0; i<weatherInfo.length; i++){
                    myWeatherReport.text += weatherInfo[i]+”\n”;
                }
            }
            function faultHandler(event:FaultEvent):void{
                Alert.show(event.fault.toString(),”WebService Error!”);
            }
            function resetWeather():void{
                myWeatherReport.text =”";
            }
        ]]>
    </mx:Script>
        <mx:WebService id=”ws” wsdl=”
    http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl”
             showBusyCursor=”true” result=”onload(event)” fault=”faultHandler(event)”/>
        <mx:VBox horizontalCenter=”center” horizontalAlign=”center”>
        <mx:TextInput id=”city” text=”上海”></mx:TextInput>
        <mx:Button label=”查询天气” click=”ws.getWeatherbyCityName(city.text)”/>
        <mx:TextArea id=”myWeatherReport” height=”500″ width=”600″ editable=”false”/>

    •  
      •     </mx:VBox>
        </mx:Application>

 

2009-08-11_152802

程式运行结果(实例):

 

在Flex中应用Google Map API建立地图应用

今天突然发现,Google Maps API 除了提供能被 Ajax 应用程序调用的 JavaScript 接口之外,还提供了能被 Flash 应用程序调用的 Flex 语言接口。一时兴趣,就做了个试验,用Flex实现我家了地理位置展示。

Flex 简介


  Flex是Adobe公司推出的技术,基于Flash平台,开发的程序可以运行于装有Flash Player插件的浏览器以及Adobe的桌面程序运行平台AIR之上,具有很好的表现力和交互力。官方网站上对Flex的定义如下:
  Adobe® Flex® 3 是用于构建和维护在所有主要浏览器、桌面和操作系统一致地部署的极具表现力的 Web 应用程序的高效率的开放源码框架。
  相对于Ajax,Flex的优点是易于开发调试,表现力交互力强,缺点是加载速度慢。在兼容性方面,我觉得Flex更好。

 
Google Map API for Flash介绍


  Google Maps API for Flash 使得 Flex 开发人员能够把 Google Map 嵌入到 Flex 应用程序中。该 API 提供了很多实用的工具用来操控 Google Map。利用该 API,您可以处理地图事件、添加地图控件、在地图上添加标记、或者在地图上面画线,也可以利用 Geocoding 将地址转换成经纬度数据。 


开发环境准备


  开发Flex应用,您需要Flex SDK或Flex Builder,前者是Adobe公司提供的开源软件开发工具包(Software Development Kit),后者是基于Eclipse专注于Flex开发的IDE.(很容易理解,Flex SDK与Flex Builder的关系犹如JDK & Eclipse).在这里,使用的是Flex Builder进行开发

一、申请Google Map API Key

申请地址:http://code.google.com/intl/zh-TW/apis/maps/signup.html

如下图所示:(请注意,如果是在本机测试,请填写http://127.0.0.1)
  flex-googlemap01接着,获取到相应的Key:
ABQIAAAARNDU8d2SSTu0rXH-GjUeMBQO8aZUyAkW5UsAyLn97mDEIA1eVxTeKnSG1ArDXiJAO5kuBkAFTCw9iw

flex-googlemap02

Google 站点 下载 Google Maps API for Flash SDK 到本地硬盘并解压。解压后在 lib 目录下会有两个 swc 文件,这些 swc 文件包含开发 Google Maps API for Flash 应用程序要用到的所有 ActionScript 类。在用 Flex 开发 Google 地图应用程序时,必须把后缀为 _flex 的 swc 文件加到项目的 Library path 中。

   好了,接下来我们就可以在Flex Builder里开发应用了,这Flex Builder中建立一个Web Project,本人编写的代码如下:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute”>
    <maps:Map xmlns:maps=”com.google.maps.*” id=”map” mapevent_mapready=”onMapReady(event)” width=”100%” height=”100%”
    key=”ABQIAAAARNDU8d2SSTu0rXH-GjUeMBQO8aZUyAkW5UsAyLn97mDEIA1eVxTeKnSG1ArDXiJAO5kuBkAFTCw9iw”/>
<mx:Script>
<![CDATA[
import com.google.maps.InfoWindowOptions;
import com.google.maps.controls.MapTypeControlOptions;
import com.google.maps.controls.MapTypeControl;
import com.google.maps.controls.ZoomControlOptions;
import com.google.maps.controls.ZoomControl;
import com.google.maps.controls.OverviewMapControlOptions;
import com.google.maps.controls.OverviewMapControl;
import com.google.maps.controls.PositionControlOptions;
import com.google.maps.controls.PositionControl;
import com.google.maps.MapEvent;
import com.google.maps.LatLng;
import com.google.maps.MapType;
private function onMapReady(event:MapEvent):void {       
this.map.setCenter(
        new LatLng(22.0473,111.0112)/*经纬度*/, 17,  MapType.NORMAL_MAP_TYPE);   
        //显示方向的按钮,用来移动地图
        map.addControl(new PositionControl(new PositionControlOptions()));
        //显示缩略图
        map.addControl(new OverviewMapControl(new OverviewMapControlOptions()));
       //显示刻度来放缩地图
       map.addChild(new ZoomControl(new ZoomControlOptions()));
       //显示地图的四种类型以随意切换
       map.addControl(new MapTypeControl(new MapTypeControlOptions()));
       map.enableScrollWheelZoom();
       map.enableContinuousZoom();
       var address:LatLng = new LatLng(map.getCenter().lat(),map.getCenter().lng());
map.openInfoWindow(address, new InfoWindowOptions({title: "Hi", content: "这是我的家"}));
}
]]>
</mx:Script>
</mx:Application>
<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute”>
   <maps:Map xmlns:maps=”com.google.maps.*” id=”map” mapevent_mapready=”onMapReady(event)” width=”100%” height=”100%”
    key=”ABQIAAAARNDU8d2SSTu0rXH-GjUeMBQO8aZUyAkW5UsAyLn97mDEIA1eVxTeKnSG1ArDXiJAO5kuBkAFTCw9iw”/>
<mx:Script>
<![CDATA[
 import com.google.maps.InfoWindowOptions;
import com.google.maps.controls.MapTypeControlOptions;
import com.google.maps.controls.MapTypeControl;
import com.google.maps.controls.ZoomControlOptions;
import com.google.maps.controls.ZoomControl;
import com.google.maps.controls.OverviewMapControlOptions;
import com.google.maps.controls.OverviewMapControl;
import com.google.maps.controls.PositionControlOptions;
import com.google.maps.controls.PositionControl;
import com.google.maps.MapEvent;
import com.google.maps.LatLng;
import com.google.maps.MapType;
private function onMapReady(event:MapEvent):void {       
this.map.setCenter(
        new LatLng(22.0473,111.0112)/*经纬度*/, 17,  MapType.NORMAL_MAP_TYPE);
           //显示方向的按钮,用来移动地图
        map.addControl(new PositionControl(new PositionControlOptions()));
         //显示缩略图
        map.addControl(new OverviewMapControl(new OverviewMapControlOptions()));
       //显示刻度来放缩地图
       map.addChild(new ZoomControl(new ZoomControlOptions()));
       //显示地图的四种类型以随意切换
       map.addControl(new MapTypeControl(new MapTypeControlOptions()));
       map.enableScrollWheelZoom();
       map.enableContinuousZoom();
       var address:LatLng = new LatLng(map.getCenter().lat(),map.getCenter().lng());
map.openInfoWindow(address, new InfoWindowOptions({title: "Hi", content: "这是我的家"}));
}
]]>
</mx:Script>
</mx:Application>

程序运行结果如下:
(刘二大排档,是我家楼下的店铺。旁边的司令大排档,曾经,我、栋科和林泳三哥们在那儿大吃了一顿,哈哈,好想家了)