视频课:https://edu.csdn.net/course/play/7621Flex常用组件(上)

学习内容

Ø Flex组件的分类

Ø Flex常用组件的使用。

Ø 使用组件处理数据和交互

Ø ActionScript3.0JavaScript交互

能力目标

Ø 掌握使用各种常用组件搭建用户界面

Ø 掌握ActionScript3.0JavaScript交互方法

 

 


本章简介

本章主要介绍如何使用Flex组件构建界面。Flex组件可分为可见组件和非可见组件。可见组件用于界面的外观设计,非可见组件为辅助应用程序的设计。例如,使用Flex非可见组件来存储数据,为一些多值可见组件提供数据源,如下拉框组件。另外,本章还着重介绍了Flex中最常用的几种组件, 包括复选框(CheckBox)、 下拉框(ComboBox)、列表框(List)、单选框(RadioButton)、输入框(Textln- put)、消息提示框(Alert)AdvancedDataGrid数据表格组件、Tree组件、MenuBar 菜单导航组件、VideoPlayer视频播放组件等。

 

  


核心技能部分


Flex应用程序的界面通常由各种各样的组件来构建。例如,一个登录框应用程序包括了标签组件、输入框组件、按钮组件等。不同的组件有其特有的功能,如按钮组件的单击动作和双击动作。用户可选择不同的组件来满足应用程序的要求。

1.1 Flex组件概述

Flex组件是指用MXML标准和ActionScript代码定义的一种可重用的控件,包括属性(Properties)、方法(Methods)、事件(Events)、样式(Styles).

  Flex 4.0中提供了许多基础的Flex组件,如文本组件、.按钮组件、下拉框组件等。组件根据是否由Adobe公司提供,可分为基础Flex组件和自定义组件。

Ø 基础Flex组件是由Adobe公司提供的最基础的Flex组件,能满足用户最基本的要求。基础Flex组件的特征是名称空间为“mx”和“s”,如按钮组件的标签为<s:Button>

Ø 自定义组件是指用户在基础Flex组件的基础上扩展生成的新组件。

  Flex组件根据组件是否可见又可分为可见组件和非可见组件。

Ø Flex可见组件是指组件在应用程序运行时是可显示状态。例如,按钮组件、下拉框组件、输入框组件等都是Flex可见组件。

Ø Flex非可见组件是指组件在应用程序中是不可显示的。例如,<s:Script>组件用于插入ActionScript3.0代码,<fx:Binding>组件用于绑定数据。这些组件都是不显示的组件。

1.2 Flex可见组件

Flex可见组件是一类最基础的组件,在构建应用程序界面时大量使用。Flex可见组件在应用程序中是可见状态,所以在设计模式下可用鼠标拖曳其位置来构建界面。

1.2.1  可见组件的分类

Flash Builder4中为了用户使用方便,将可见组件分成以下几类:

Ø 定制:存放用户自定义组件。

Ø 控件:存放基础的控制组件,如按钮组件,文本组件,下接框组件,这里存放了最基础的可见组件。

Ø 数据控件:存放数据呈现组件,如网格组件、下拉列表组件、树组件等。这里存放了和数据显示相关的组件。

Ø 布局:存放布局组件,如窗口组件、表单组件。这里存放了与布局相关的组件。

Ø 导航器:存放导航组件,如Tab条组件、按钮条组件。

Ø Adobe AIR组件:存放Adobe AIR组件。Adobe AIR组件是Flex3.0中新增的组件,主要是桌面应用程序的相关组件。例如,可嵌套网页的HTML组件,打开本地文件系统的FileSystemLIst组件。

Ø 图表:存放图表组件。例如,面积图表声AreaChart组件,直方图表ColumnChart组件。

1.3 Flex非可见控件

Flex非可见组件的使用方法是在MXML编辑器的代码模式下手工添加。例如,在MXML文件中添加<fx:script>组件的步骤如下。

(1) 单击MXML编辑器上方的“源代码”按钮,进入‘MXML编辑器切换至代码模式。

(2) <s:Application>标签下手工添加<fx:script>组件。此时MXML编辑器会有相应的代码提示。

1.3.1 <fx:Declarations>标签

在新的Flex4.0中,把可视化组件与非可视化完全分离开。可以把非可视化组件放在标签内,如效果组件、数据组件(包括XML, XMListArray)Model模型组件、数据验证组件等。同时也可以在自定义的组件中,Declarations标签来定义属性。如下面的代码,在Declarations标签中定义了一个非可视化的String标签组件,并设置属性的值。代码如下:

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Declarations>

<fx:String id="btnlab">按钮标签</fx:String>

</fx:Declarations>

<s:Button label="{btnlab}"/>

</s:Application>

 

运行的效果如图3.1.1所示。

 

3.1.1 使用Declarations标签

Declarations标签实际也可以看做是声明了一个全局变量,在外部可以重复调用,这样也增强了代码的重用性,为项目整体架构的设计也提供了方便。

1.3.2 LibraryDefinition标签

使用definition标签可以定义一组FxG格式的图形。definition标签通常被定义在Library标签内,所以,在Library标签中,可以通过定义多个definition标签来创建多组FxG图形组件。下面的代码,绘制若干个矩形,并有效地排列位置。代码如下:

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">


<fx:Library>

<fx:Definition  name="mySquare">

<s:Group>

<s:Rect width="100%" height="100%">

<s:stroke>

<s:SolidColorStroke color="red"/>

</s:stroke>

</s:Rect>

</s:Group>

</fx:Definition>

</fx:Library>

<s:layout>

<s:BasicLayout/>

</s:layout>


<fx:mySquare width="20" height="20" x="25" y="25"/>

<fx:mySquare width="20" height="20" x="50" y="25"/>

<fx:mySquare width="20" height="20" x="50" y="50"/>

<fx:mySquare width="20" height="20" x="75" y="50"/>

</s:Application>

 

运行的效果如图3.1.2所示。

 

3.1.2 使用library definition标签

FXGFlex4.0中新增加的内容,其目的就是为了更好的数据交换。有关FXG相关的知识,在后面章节中也有详细的介绍。

1.3.3 Private标签

定义在Private标签的元素,在编译器编译的时候,会忽略掉其内的所有标签。并月Private标签必须放在文档的最后。如下面的代码,在Private标签中,定义编写代码的相关信息,包括作者、时间等。代码如下:

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">


<fx:Library>

<fx:Definition  name="mySquare">

<s:Group>

<s:Rect width="100%" height="100%">

<s:stroke>

<s:SolidColorStroke color="red"/>

</s:stroke>

</s:Rect>

</s:Group>

</fx:Definition>

</fx:Library>

<s:layout>

<s:BasicLayout/>

</s:layout>


<fx:mySquare width="20" height="20" x="25" y="25"/>

<fx:mySquare width="20" height="20" x="50" y="25"/>

<fx:mySquare width="20" height="20" x="50" y="50"/>

<fx:mySquare width="20" height="20" x="75" y="50"/>

<fx:Private>

<date>

2012年元月1

</date>

<author>

alen

</author>

</fx:Private>

</s:Application>

编译时,Private标签里面的内容不会被编译到输入文件中。在大部分的情况下,private标签只是起到一个标记相关信息的作用。

1.4 Flex常用组件

Flex组件数量众多、功能各异,。组件是开发Flex应用的基石,Flex的大部分组件都位于spark.componentsmx.controls包中。处理数据和实现用户交互是Flex程序的一大特色。 本节主要介绍Flex应用程序中常用的一些组件。包括按钮组件、下拉框组件、列表组件等。

1.4.1 复选框( CheckBox)

  CheckBox的重要属性如下:

(1) label:设置CheckBox显示的标题。

(2) selected:检验复选框是否被选中,选中为True,否则为False

示例 3.1

 

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Declarations>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

</fx:Declarations>

<fx:Style>

@namespace s "library://ns.adobe.com/flex/spark";

@namespace mx "library://ns.adobe.com/flex/mx";

.selectedStyle {

color: green;

}


.unselectedStyle {

color: red;

}

</fx:Style>

<fx:Script>

<![CDATA[

private function checkBox_change(evt:Event):void {

var tgt:CheckBox = evt.currentTarget as CheckBox;

if (tgt.selected) {

tgt.styleName = "selectedStyle";

} else {

tgt.styleName = "unselectedStyle";

}

}

]]>

</fx:Script>


<s:CheckBox id="checkBox"

 label="CheckBox"

 selected="false"

 styleName="unselectedStyle"

 horizontalCenter="0"

 verticalCenter="0"

 change="checkBox_change(event);" />



</s:Application>

示例3.1运行后 效果如图3.1.3所示。

 

3.1.3 CheckBox示例

1.4.2 下拉框组件ComboBox

下拉框组件主要应用于选择一项数据。下拉框组件属于多值组件,其值可由多种数据源提供。例如,下拉框组件的数据来自ArrayCollectionArrayList 和 XMLListCollection等。下拉框组件的DataProvider属性指明数据来源。方法是使用“{}”操作符绑定数据源。

下拉框与列表框的重要属性如下: 

(1) dataProvider:指定下拉框与列表框的数据提供者,

(2) labelField:指定用于显示文本的字段名。 

(3) prompt:指定未选择列表项时的初始化提示文本。 

下拉框组件的其他常用属性如表2-1-1所示.

2-1-1 下拉框组件的其他常用属性

属性名

说明

itemRenderer

自定义下拉框数据显示形式

itemRenderer

自定义下拉框数据显示形式

selectedIndex

返回选中数据的索引号,类型为int

selectedItem

返回选中数据,类型为object

selectedLabel

返回选中数据的字符串

 

下拉框组件的常用事件如表2-1-2所示。

2-1-2下拉框组件的常用事件

事件名

说明

Change

选择数据发生变化的事件

Open

打开下拉框的事件

Close

关闭下拉框组件的事件

示例:3.2

<?xml version="1.0"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<!--这个例子实现的是一个ComboBox下拉列表框,列表的选项是由绑定数组为数据源的.当关闭(选择)列表时,被选中的值进行了传递,又由closeHandler函数对label进行了赋值(修改)-->

<fx:Script>

<![CDATA[

import mx.collections.ArrayCollection;




public var cards:ArrayCollection = new ArrayCollection(

[ {label:"Visa",data:1},

{label:"MasterCard", data:2},

{label:"American Express", data:3} ]);


private function closeHandler(event:Event):void {

myLabel.text = "您选择了: " +  ComboBox(event.target).selectedItem.label;//targhtevent事件的目标;ComboBox具有selectedItem属性

myData.text = "Data: " +  ComboBox(event.target).selectedItem.data;

}     

]]>

</fx:Script>


<s:Panel title="ComboBox Control Example"

  height="75%" width="75%"


  color="0xffffff" borderAlpha="0.15">

<s:layout>

<s:HorizontalLayout/>

</s:layout>

<s:ComboBox dataProvider="{cards}" width="150" color="0x000000"

 close="closeHandler(event);"/>


<s:VGroup width="250" color="0x000000">

<mx:Text  width="200" color="blue" text="请选择信用卡"/>

<mx:Label id="myLabel" text="您选择了:"/>

<mx:Label id="myData" text="Data:"/>

</s:VGroup>        


</s:Panel>    

</s:Application>

示例3.2运行后 效果如图3.1.4所示。

 

 

3.1.4 下拉框示例

示例 3.3

countries_states.xml

<item>

<country name="中国">

<state>郑州</state>

<state>北京</state>

<state>上海</state>

</country>

 

<country name="美国">

<state> 纽约</state>

<state>华盛顿</state>

<state>旧金山</state>

</country>

</item>

 

MXML

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955"  

minHeight="600">


<fx:Declarations>

<fx:XML id="dp" source="countries_states.xml">


</fx:XML>

</fx:Declarations>


  <fx:Script>


</fx:Script>

 

   

            <mx:ComboBox id="countryCB" dataProvider="{this.dp.country}" labelField="@name"  

/>

        

       

            <mx:ComboBox id="stateCB" dataProvider="{countryCB.selectedItem.state}" />

 

     

    

 

</s:Application>

 

示例 3.3 运行效果如图3.1.5所示。

 

3.1.5 下拉框示例

1.4.3 单选框( RadioButton) 

RadioButton举选框的重要属性如下: 

(1) label:设置RadioButton显示的标题。 

(2) groupName:指定单选框所在的组,通过使用该属性实现单选框按钮组。

(3) selected:检测单选框是否被选中,选中为True.否则为False 

示例:3.4

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">





<fx:Script>

<![CDATA[

import mx.controls.Alert;


private function checkAnswers():void {

var success:Boolean = true;


success = checkGroup(q1_group) && success;

success = checkGroup(q2_group) && success;


Alert.show("SUCCESS = " + success);

}


private function checkGroup(rbg:RadioButtonGroup):Boolean {

var rb:RadioButton;

var valid:Boolean = true;

var i:int;



if (rbg.selectedValue != true) {


valid = false;


rb = rbg.selection;


if (rb != null) {


rb.includeInLayout = false;

rb.visible = false;

}


} else {


for (i = 0; i < rbg.numRadioButtons; i++) {


rb = rbg.getRadioButtonAt(i);


if (!rb.selected) {


rb.includeInLayout = false;

rb.visible = false;

}

}

}



return valid;

}

]]>

</fx:Script>

<fx:Declarations>

<mx:RadioButtonGroup id="q1_group" enabled="false" />

<mx:RadioButtonGroup id="q2_group" enabled="false" />

</fx:Declarations>



<s:Panel title="Subject: Periodic Table" width="100%" height="100%">

<s:layout>

<s:VerticalLayout horizontalAlign="center">


</s:VerticalLayout>

</s:layout>

<s:VGroup styleName="QuestionVBox" width="100%">

<mx:Text styleName="QuestionText"

 selectable="false"

 width="100%">

<mx:text>1) Which three groups of the Periodic Table contain the most elements classified as metalloids (semimetals)?</mx:text>

</mx:Text>


<!-- Wrong -->

<mx:RadioButton id="q1_a"

label="1, 2, and 13"

group="{q1_group}" />

<!-- Wrong -->

<mx:RadioButton id="q1_b"

label="2, 13, and 14"

group="{q1_group}" />

<!-- RIGHT -->

<mx:RadioButton id="q1_c"

label="14, 15, and 16"

group="{q1_group}"

value="true" />

<!-- Wrong -->

<mx:RadioButton id="q1_d"

label="16, 17, and 18"

group="{q1_group}" />

</s:VGroup>


<s:VGroup styleName="QuestionVBox" width="100%">

<mx:Text styleName="QuestionText"

 selectable="false"

 width="100%">

<mx:text>2) Which element has the highest first ionization energy?</mx:text>

</mx:Text>


<!-- Wrong -->

<mx:RadioButton id="q2_a"

label="sodium"

group="{q2_group}" />

<!-- Wrong -->

<mx:RadioButton id="q2_b"

label="aluminum"

group="{q2_group}" />

<!-- Wrong -->

<mx:RadioButton id="q2_c"

label="calcium"

group="{q2_group}" />

<!-- RIGHT -->

<mx:RadioButton id="q2_d"

label="phosphorus"

group="{q2_group}"

value="true" />

</s:VGroup>



<mx:Button label="Check answers"

   click="checkAnswers();" />


</s:Panel>


</s:Application>

示例3.4的运行结果如图3.1.6所示。

 

 

3.1.6 单选框示例

1.4.4 输入框( Textlnput) 

输入框的重要属性如下: 

(1)maxChars:限制输入框能够容纳的最大字符数,每个汉字的长度为l 

(2) editable:决定输入框是否能够编辑,True表示可以编辑。 

(3) restrict:限定输入框能接受的字符,支持正则表达式,例如: 

1) restrict=“0-9”:表示输入框只能接受数字。 

2) restrict=“0-9.”:表示输入框只能接受数字和小数点。 

3) restrict“0-9a-zA-Z”:表示输入框只能接受数字与英文字母。 

(4) text:获取用户在输入框中输入的文本。 

(5) displayAsPassword:决定是否密码框

示例3.5

<s:Panel width="334" height="200" horizontalCenter="0" verticalCenter="0" click="panel1_clickHandler(event)">

<s:TextInput x="119" y="15" restrict="a-zA-Z" maxChars="8" />

<s:TextInput x="119" y="55" displayAsPassword="true" restrict="0-9"/>

<s:Label x="25" y="15" text="用户名"/>

<s:Label x="25" y="59" text="密码"/>

</s:Panel>

1.4.5 消息提示框 

Alert组件是一个带有提示信息的弹出式对话框。通常情况下,此组件用于各种重要信息提示,需要用户确认或选择。Alert组件的出现将暂时中止当前所有用户交互动作,真到用户关闭窗口为止。

示例3.6

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>


<fx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.events.CloseEvent;


[Embed(source="assets/bullet_green.png")]

     private var BulletCritical:Class;

 

protected function alert_close(event:CloseEvent):void//注意这里是closeevent

{

if(event.detail==Alert.YES){

Alert.show('删除中...');

}

}

protected function button1_clickHandler(event:MouseEvent):void

{


Alert.show("你确实想退出吗?",'这是title',Alert.NO|Alert.YES|Alert.NONMODAL,null,alert_close,BulletCritical);//注意这里方法不用传参数

//null 是指父容器 可以传this 也可不传

}

]]>

</fx:Script>

 

<fx:Declarations>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

</fx:Declarations>

<s:Button x="114" y="130" label="按钮" click="button1_clickHandler(event)" />

</s:Application>

示例3.6 运行效果如图3.1.7所示。

 

3.1.7 Alert示例

1.4.6 AdvancedDataGrid组件

HTML页面的表格类似,AdvancedDataGrid组件用于以行、列的格式显示数据。 

(l)使用AdvancedDataGrid展示简单数据。 

示例3.7

<?xml version="1.0"?>

<!-- itemRenderers\sparkmx\SparkDGInlineRenderer.mxml -->

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    width="650">

    

    <fx:Script>

        <![CDATA[

import mx.collections.ArrayCollection;

import mx.controls.Alert;

import mx.events.ListEvent;

            

            

                

            private var initDG:ArrayCollection = new ArrayCollection([

                {Artist:'Pavement', Album:'Slanted and Enchanted',

                    Price:11.99, Cover: '../assets/slanted.jpg', Rating:'none'},

                {Artist:'Pavement', Album:'Brighten the Corners',

                    Price:11.99, Cover: '../assets/brighten.jpg', Rating:'none'}

            ]);

 

protected function myGrid_changeHandler(event:ListEvent):void

{

Alert.show("您选择的唱片为:"+event.target.selectedItem.Album+"  价格:"+event.target.selectedItem.Price);


}

 

        ]]>

    </fx:Script>

 

    <mx:AdvancedDataGrid id="myGrid" height="400" width="600"

        dataProvider="{initDG}" editable="true" change="myGrid_changeHandler(event)">  

        <mx:columns>

            <mx:AdvancedDataGridColumn dataField="Artist"/>

<mx:AdvancedDataGridColumn dataField="Album"/>

<mx:AdvancedDataGridColumn dataField="Rating" >

               

            </mx:AdvancedDataGridColumn>

<mx:AdvancedDataGridColumn dataField="Cover" />

<mx:AdvancedDataGridColumn dataField="Price"/>

        </mx:columns>       

    </mx:AdvancedDataGrid>  

</s:Application>

在示例3.7中,columns标签定义了AdvancedDataGrid的所有列,AdvancedDataGridColumn代表其中一列.dataField对应于数据源中的属性名,headerText标明了该列的标题。示例3.7的运行结果如图3.1.8、图3.1.9所示.

 

3.1.8  AdvancedDataGrid示例

 

3.1.9  AdvancedDataGrid示例

 

(2)对数据进行分组。 

对数据进行分组是AdvancedDataGrid的常见要求。分组特性允许选择一个数据字段,并以类似Tree组件的方式用该字段对数据分组。以商品分类为例,对数据进行分组的步骤如下: 

Ø <mx: AdvancedDataGrid>标签中移除dataProvider属性,并在<mx: AdvancedDataGrid>组件中插入一个<mx:dataProvider>标签。 

Ø dataProvider标签对中,嵌入一对GroupingCollection标签,指定其id属性并将source属性绑定到数据源上。GroupingCollection类允许分组数据。通过设置其属性可以指定需要分组的数据、数据如何分组以及数据在何处显示等。 

Ø GroupingCollection块内嵌入一对<mx:Grouping>标签。在Grouping块中,可以使用<mx GroupingField>标签,通过name属性指定了分组数据所依据的字段。

Ø AdvancedDataGrid添加creationComplete事件,指定其执行refresh()。实际上GroupingCollection类的refresh方法对数据进行了分组。 

示例 3.8,分组的AdvancedDataGrid代码如下: 

<?xml version="1.0"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    width="650">

    

    <fx:Script>

        <![CDATA[

import mx.collections.ArrayCollection;

import mx.controls.Alert;

import mx.events.FlexEvent;

import mx.events.ListEvent;

            

            

                

            private var initDG:ArrayCollection = new ArrayCollection([

                {Artist:'Pavement', Album:'Slanted and Enchanted',

                    Price:11.99, Cover: '../assets/slanted.jpg', Rating:'none'},

                {Artist:'Pavement', Album:'Brighten the Corners',

                    Price:11.99, Cover: '../assets/brighten.jpg', Rating:'great'},

{Artist:'陆峰', Album:'落单候鸟',

Price:8, Cover: '../assets/brighten.jpg', Rating:'no good'},

{Artist:'卓文萱', Album:'反正卓文萱',

Price:10, Cover: '../assets/brighten.jpg', Rating:'good'},

{Artist:'李克勤', Album:'似曾相识',

Price:12, Cover: '../assets/brighten.jpg', Rating:'great'},

{Artist:'李克勤', Album:'红日',

Price:6, Cover: '../assets/brighten.jpg', Rating:'good'},

{Artist:'李克勤', Album:'护花使者',

Price:9, Cover: '../assets/brighten.jpg', Rating:'none'},

{Artist:'李克勤', Album:'无名',

Price:10, Cover: '../assets/brighten.jpg', Rating:'none'}

            ]);

 


 

 

protected function myGrid_creationCompleteHandler(event:FlexEvent):void

{

this.gc.refresh();

}

 

 


        ]]>

    </fx:Script>

 

    <mx:AdvancedDataGrid  id="myGrid" height="400" width="600"

        

designViewDataType="tree"


creationComplete="myGrid_creationCompleteHandler(event)"

>  

      <mx:dataProvider>

  <mx:GroupingCollection id="gc" source="{initDG}">

  <mx:Grouping>

  <mx:GroupingField name="Artist"/>

  </mx:Grouping>

  </mx:GroupingCollection>

  </mx:dataProvider>

        <mx:columns>

            <mx:AdvancedDataGridColumn dataField="Artist"/>

<mx:AdvancedDataGridColumn dataField="Album"/>

<mx:AdvancedDataGridColumn dataField="Rating" >

               

            </mx:AdvancedDataGridColumn>

<mx:AdvancedDataGridColumn dataField="Cover" />

<mx:AdvancedDataGridColumn dataField="Price"/>

        </mx:columns>       

    </mx:AdvancedDataGrid>  

</s:Application>

 

示例3.8运行效果如图3.1.10所示。

 

3.1.10 数据分组

 

(3)显示摘要数据。 

在表格中显示数据往往表示需要显示这些数据的摘要信息。例如,根据区域显示销售数据时, 要显示每个区域的摘要数据。显示摘要的步骤如下: 

Ø 添加1<mx:AdvancedDataGridColumn>列作为摘要的列。 <mx:AdvancedDataGridColumn dataField="销量合计"/>

Ø GroupingField块内插入1<mx:summaries>标签。可以通过使用GroupingField类的summaries属性创建分组的摘要数据。 

Ø summaries块中插入一对<mx:SummaryRow>标签。向SummaryRow的起始标签中添summaryPlacement属性并设置为last,该属性用于指定摘要显示的位置,last表示摘要显示在的最后一行。在SummaryRow块中嵌入一对<mx:fields>标签,并在这对标签中嵌入一个<mx:SummaryField>标签。SummaryField类的dataField属性指定用于摘要统计的数据源字段;operation指定摘要数据应如何计算,可以取SUM1WNMAXAVGCOUNT等;label属性用于将摘要值关联到某一属性上。在本例中,属性名为销量合计,该属性对应<mx:AdvanccdDataGridColumn  dataField=” 销量合计>列的dataField属性。 

示例 3.9 最终分组摘要显示的AdvancedDataGrid代码如下 

<?xml version="1.0"?>

<!-- itemRenderers\sparkmx\SparkDGInlineRenderer.mxml -->

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    width="650">

    

    <fx:Script>

        <![CDATA[

import mx.collections.ArrayCollection;

import mx.controls.Alert;

import mx.events.FlexEvent;

import mx.events.ListEvent;

            

            

                

            private var initDG:ArrayCollection = new ArrayCollection([

                {Artist:'Pavement', Album:'Slanted and Enchanted',

                    sal:119, Cover: '../assets/slanted.jpg', Rating:'none'},

                {Artist:'Pavement', Album:'Brighten the Corners',

                    sal:19, Cover: '../assets/brighten.jpg', Rating:'great'},

{Artist:'陆峰', Album:'落单候鸟',

sal:80, Cover: '../assets/brighten.jpg', Rating:'no good'},

{Artist:'卓文萱', Album:'反正卓文萱',

sal:100, Cover: '../assets/brighten.jpg', Rating:'good'},

{Artist:'李克勤', Album:'似曾相识',

sal:102, Cover: '../assets/brighten.jpg', Rating:'great'},

{Artist:'李克勤', Album:'红日',

sal:61, Cover: '../assets/brighten.jpg', Rating:'good'},

{Artist:'李克勤', Album:'护花使者',

sal:92, Cover: '../assets/brighten.jpg', Rating:'none'},

{Artist:'李克勤', Album:'无名',

sal:101, Cover: '../assets/brighten.jpg', Rating:'none'}

            ]);

 


 

 

protected function myGrid_creationCompleteHandler(event:FlexEvent):void

{

this.gc.refresh();

}

 

 


        ]]>

    </fx:Script>

 

    <mx:AdvancedDataGrid  id="myGrid" height="400" width="600"

        

designViewDataType="tree"


creationComplete="myGrid_creationCompleteHandler(event)"

>  

      <mx:dataProvider>

  <mx:GroupingCollection id="gc" source="{initDG}">

  <mx:Grouping>

  <mx:GroupingField name="Artist">

   <mx:summaries>

<mx:SummaryRow summaryPlacement="last">

<mx:fields>

<mx:SummaryField operation="SUM" dataField="sal" label="销量合计"/>

</mx:fields>

</mx:SummaryRow>

</mx:summaries>

  </mx:GroupingField>

  </mx:Grouping>

  </mx:GroupingCollection>

  </mx:dataProvider>

        <mx:columns>

            <mx:AdvancedDataGridColumn dataField="Artist"/>

<mx:AdvancedDataGridColumn dataField="Album"/>

<mx:AdvancedDataGridColumn dataField="Rating" >

               

            </mx:AdvancedDataGridColumn>

<mx:AdvancedDataGridColumn dataField="Cover" />

<mx:AdvancedDataGridColumn dataField="sal"/>

<mx:AdvancedDataGridColumn dataField="销量合计"/>

        </mx:columns>       

    </mx:AdvancedDataGrid>  

</s:Application>

运行应用,结果如图3.1.11所示.

 

3.1.11 显示摘要信息

(4)AcilvancedDataGrid中使用itemRenderer内联渲染器。 

Flex提供的大多数List组件都会有itemRenderer属性,一般情况下.List组件以默认的形式展示数据,但用户可以根据实际需要覆盖默认的最示方式,而itemRenderer是用于实现自定义显示方式的内联渲染器。自定义的itemRenderer相当于一个简单的自定义组件,同样,其中可以放置其他组件来表现舞加丰富的内容。这样,List组件的内容将不再局限于文字,还可以显示图片等内容。itemRenderer的组件有一个共同特点,即拥有一个名为“data”的属性。List组件通过设置itemRendererdata属性为每个itemRenderer实例提供dataProvider的记录。例如,封面和评价进行处理,步骤如下:  

Ø Cover Rating列中嵌入一对<mx:itemRenderer>标签,定义内联渲染器。

Ø <mx:itemRenderer>块中嵌入一对<fx:Component>标签,该组件将通知Flex编译器正在定义一个组件内联。 

Ø <fx:Component>块中嵌入1<mx:Canvas>标签,该标篇的功能与<s:group>功能近似, 即定义一个容器.该容器会装载其他的Flex组件。 

Ø <mx:Canvas>块中嵌入Flex其他的组件。此处嵌入ImageDropDownList组件。 

示例3.10,修改后的AdvancedDataGrid代码如下: 

<?xml version="1.0"?>

<!-- itemRenderers\sparkmx\SparkDGInlineRenderer.mxml -->

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

   

xmlns:mx="library://ns.adobe.com/flex/mx"

    width="650">

    

    <fx:Script>

        <![CDATA[

import mx.collections.ArrayCollection;

import mx.controls.Alert;

import mx.events.ListEvent;

                            

            private var initDG:ArrayCollection = new ArrayCollection([

                {Artist:'Pavement', Album:'Slanted and Enchanted',

                    Price:11.99, Cover: 'assets/brighten.jpg', Rating:'none'},

                {Artist:'Pavement', Album:'Brighten the Corners',

                    Price:11.99, Cover: 'assets/brighten.jpg', Rating:'great'},

{Artist:'陆峰', Album:'落单候鸟',

Price:8, Cover: 'assets/brighten.jpg', Rating:'no good'},

{Artist:'卓文萱', Album:'反正卓文萱',

Price:10, Cover: 'assets/brighten.jpg', Rating:'good'},

{Artist:'李克勤', Album:'似曾相识',

Price:12, Cover: 'assets/brighten.jpg', Rating:'great'},

{Artist:'李克勤', Album:'红日',

Price:6, Cover: 'assets/brighten.jpg', Rating:'good'},

{Artist:'李克勤', Album:'护花使者',

Price:9, Cover: 'assets/brighten.jpg', Rating:'none'},

{Artist:'李克勤', Album:'无名',

Price:10, Cover: 'assets/brighten.jpg', Rating:'none'}

            ]);

        ]]>

    </fx:Script>

 

    <mx:AdvancedDataGrid  id="myGrid" height="400" width="600"

        dataProvider="{initDG}" >  

        <mx:columns>

            <mx:AdvancedDataGridColumn dataField="Artist"/>

<mx:AdvancedDataGridColumn dataField="Album"/>

<mx:AdvancedDataGridColumn  >

<mx:itemRenderer >

<fx:Component>

<mx:Canvas>

<fx:Script>

<![CDATA[

import mx.collections.ArrayList;

]]>

</fx:Script>


<s:DropDownList id="dd" top="5" left="5"

selectedItem="{data.Rating}"

initialize="dd.dataProvider = new ArrayList(['none', 'no good', 'good', 'great'])"/>

</mx:Canvas>

</fx:Component>



</mx:itemRenderer>

</mx:AdvancedDataGridColumn>

<mx:AdvancedDataGridColumn >

<mx:itemRenderer >

<fx:Component>

<mx:Canvas>

 

<fx:Script>

<![CDATA[

import mx.controls.Alert;

protected function albumImage_clickHandler(event:MouseEvent):void

{

Alert.show(data.Cover+'');

}

]]>

</fx:Script>

 

<mx:Image id="albumImage" height="50" width="50"  source="{data.Cover}"

  click="albumImage_clickHandler(event)"

  />

</mx:Canvas>

</fx:Component>



</mx:itemRenderer>

</mx:AdvancedDataGridColumn>

<mx:AdvancedDataGridColumn dataField="Price"/>

</mx:columns>       

 


              

    </mx:AdvancedDataGrid>  

</s:Application>

运行应用,结果如图3.1.12所示。 

 

3.1.12 使用内联渲染器

1.4.7 Tree组件

Tree组件(一般称为树形控件)是List组件变异后的产物。Tree组件在显示数据时保留了层级结构,每个元素都是一个分支或叶子,分支包含其他分支或叶子,叶子不可再分。Tree组件的这中结构与XML相同,适用于以XML数据作为Tree组件的数据源。其重要属性如下: 

(l) IabelField:显示的文本所对应的XML字段。例如, “@title”表示以XML数据源中title字段的值作为Tree显示的文本,其中“@”符号后表示的名称是XML节点的属性名,是ActionScri XML数据的专用表达式。 

(2) dataProvider:指定Tree的数据提供者。 

示例:3.11

<?xml version="1.0"?>

<!-- dpcontrols/TreeEvents.mxml -->

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx">

    <s:layout>

        <s:VerticalLayout/>

    </s:layout>

    

   <fx:Script>

      <![CDATA[

         import flash.events.*;

         import mx.events.*;

         import mx.controls.*;

 

         private function changeEvt(event:Event):void {

            var theData:String = ""

            if (event.currentTarget.selectedItem.@data) {

               theData = " Data: " + event.currentTarget.selectedItem.@data;

            }

            forChange.text = event.currentTarget.selectedItem.@label + theData;

         }

 

      private function itemOpenEvt(event:TreeEvent):void {

         forOpen.text = event.item.@label;

      }

   ]]>

   </fx:Script>

 

   <mx:Tree id="XMLTree1" width="150" height="170"

          labelField="@label" itemOpen="itemOpenEvt(event);"

          change="changeEvt(event);"

          folderOpenIcon="@Embed(source='assets/bullet_green.png')"

    folderClosedIcon="@Embed(source='assets/bullet_red.png')"

    defaultLeafIcon="@Embed(source='assets/bullet_yellow.png')">

         

     

         <fx:XMLList id="MailBox">

            <node label="Mail" data="100">

               <node label="Inbox" data="70"/>

               <node label="Personal Folder" data="10">

                  <node label="Business" data="2"/>

                  <node label="Demo" data="3"/>

                  <node label="Personal" data="0" isBranch="true" />

                  <node label="Saved Mail" data="5" />

               </node>

               <node label="Sent" data="15"/>

               <node label="Trash" data="5"/>

            </node>

         </fx:XMLList>

      

   </mx:Tree>

 

 

      

            <s:Label id="forChange" width="150"/>          

      

      

            <s:Label id="forOpen" width="150"/>            

        

   

</s:Application>

运行示例3.10 效果如图3.1.13所示。

 

3.1.13 Tree控件示例

 

 

示例:3.11 演示了动态的添加和删除树的节点。

<?xml version="1.0"?>

 

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx">

    <s:layout>

        <s:VerticalLayout/>

    </s:layout>

 

    <fx:Script>

        <![CDATA[

            import mx.collections.XMLListCollection;

            

            [Bindable]

            private var company:XML =

              <list>

                <department title="Finance" code="200">

                    <employee name="John H"/>

                    <employee name="Sam K"/>

                </department>

                <department title="Operations" code="400">

                    <employee name="Bill C"/>

                    <employee name="Jill W"/>

                </department>                    

                <department title="Engineering" code="300">

                    <employee name="Erin M"/>

                    <employee name="Ann B"/>

                </department>                                

              </list>;

              

            

            private var companyData:XMLListCollection =

                new XMLListCollection(company.department);

            

            private function treeLabel(item:Object):String {

                var node:XML = XML(item);

                if( node.localName() == "department" )

                    return node.@title;

                else

                    return node.@name;

            }

 

            private function addEmployee():void {

                var newNode:XML = <employee/>;

                newNode.@name = empName.text;

                var dept:XMLList =company.department.(@title == "Operations");

                if( dept.length() > 0 ) {

                    dept[0].appendChild(newNode);

                    empName.text = "";

                }

            }

 

            private function removeEmployee():void {

                var node:XML = XML(tree.selectedItem);

                if( node == null ) return;

                if( node.localName() != "employee" ) return;

            

                var children:XMLList = XMLList(node.parent()).children();

                for(var i:Number=0; i < children.length(); i++) {

                    if( children[i].@name == node.@name ) {

                        delete children[i];

                    }

                }

            }

        ]]>

    </fx:Script>

    

    <mx:Tree id="tree"

        top="72" left="50"

        dataProvider="{companyData}"

        labelFunction="treeLabel"

        height="225" width="300"/>

    

    <mx:VBox>

        <mx:HBox>           

            <mx:Button label="Add Operations Employee" click="addEmployee();"/>

            <mx:TextInput id="empName"/>            

        </mx:HBox>

        <mx:Button label="Remove Selected Employee" click="removeEmployee();"/>                     

    </mx:VBox>

</s:Application>

运行示例3.11 效果如图3.1.14所示。

 

3.1.14 动态添加删除树节点

1.4.8 使用菜单导航

菜单在程序中的用途较广泛,它具有体积小、使用方便的特点,而且可以合理利用空间,使用户的操作更加直观、简便,是系统导航的理想选择。Flex使用MenuBar组件实现菜单.Menubar支持XML数据和数组作为数据源。 

示例 3.12

<?xml version="1.0"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx" >

 

   

    <mx:MenuBar id="myMenuBar" labelField="@label">

        <fx:XMLList>

            <menuitem label="MenuItem A">

                <menuitem label="SubMenuItem A-1" enabled="false"/>

                <menuitem label="SubMenuItem A-2"/>

            </menuitem>

            <menuitem label="MenuItem B"/>

            <menuitem label="MenuItem C"/>

            <menuitem label="MenuItem D">

                <menuitem label="SubMenuItem D-1"

                    type="radio" groupName="one"/>

                <menuitem label="SubMenuItem D-2"

                    type="radio" groupName="one"

                    selected="true"/>

                <menuitem label="SubMenuItem D-3"

                    type="radio" groupName="one"/>

            </menuitem>

        </fx:XMLList>

    </mx:MenuBar>

</s:Application>

示例3.12中创建一个具有多级菜单的应用,运行后的结果如图3.1.15所示。

 

3.1.15 菜单示例

 

另外Menu控件还可以调用其show方法,控制其在需要的地方弹出,示例2.13演示了Menushow方法的使用:

<?xml version="1.0"?>

 

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx" >

 

    <fx:Script>

        <![CDATA[

            // Import the Menu control.

            import mx.controls.Menu;

 

            // Create and display the Menu control.

            private function createAndShow():void {

                var myMenu:Menu = Menu.createMenu(null, myMenuData, false);

                myMenu.labelField="@label";

                myMenu.show(10, 10);

            }

        ]]>

    </fx:Script>

 

    <fx:Declarations>

        <fx:XML format="e4x" id="myMenuData">

            <root>

                <menuitem label="MenuItem A" >

                    <menuitem label="SubMenuItem A-1" enabled="false"/>

                    <menuitem label="SubMenuItem A-2"/>

                </menuitem>

                <menuitem label="MenuItem B" type="check" toggled="true"/>

                <menuitem label="MenuItem C" type="check" toggled="false"/>

                <menuitem type="separator"/>     

                <menuitem label="MenuItem D" >

                    <menuitem label="SubMenuItem D-1" type="radio"

                        groupName="one"/>

                    <menuitem label="SubMenuItem D-2" type="radio"

                        groupName="one" toggled="true"/>

                    <menuitem label="SubMenuItem D-3" type="radio"

                        groupName="one"/>

                </menuitem>

            </root>

        </fx:XML>

    </fx:Declarations>

 

    <mx:VBox>

        <mx:Button id="myButton"

            label="Open Menu"

            click="createAndShow();"/>

    </mx:VBox>

</s:Application>

 

 

 

示例2.13运行效果如图3.1.16所示。

 

3.1.16 菜单控件的show方法

1.4.9  AIR常用组件

文件系统组件

文件目录浏览器能浏览本地文件目录,类似于Windows的资源浏览器。在Flex3.0之前,Adobe公司出于安全性考虑,一直没有提供访问本地文件的API函数及组件。Flex 3 .0提供了可操作本地文件目录的组件,如FileSystemCOmboBoxFileSystemDataGrid,FileSystemTree

Flex3.0中也新增了File类,包含在flah.filesystem.File中。Flex3 .0只支持在AIR工程中使用File类及可操作本地文件的组件。传统的Flex工程中并不支持对本地文件的操作。下面就通过一个简单的文件目录浏览器来演示AIR控件的简单实用。

创建AIR程序的步骤如下。

Ø 选择【文件】---【新建】---flex项目】命令,弹出【创建flex项目】对话框。

Ø “项目名“文本框中输入工程名称。“应用程序类型”选择框中选择“Desktop(runs in AIR),“应用程序服务器类型”选择框可选择“无/其他”。单击【完成】按钮 ,如图3.1.17所示。

 

2.1.17 创建AIR应用

    

文件系统组件都有一个directory属性,用以指明当前文件路径。例如,设置FileSystemDataGrid组件初始路径的语法如下。

  <mx:FileSystemDataGrid id="filedg" width="100%" height="400" directory="初始文件路径"/>     

directory属性的类型是File类型,所以不能将形如“c:/”的字符串直接赋值给此属性,需要进行转换。File类型使用字符串类型构造的语法如下。

    var File变量:File=new File字符串;

    以下代码定义File类型f

     Var f:File=new File(“c:/”);

    文件系统组件directory属性变化时会触发directorChange事件。用户可根据需要做相应的处理。

上面的代码中将FileSystemDataGrid组件的directory属性初始化为指向C盘。FileSystemComboBox组件的directory属性绑定到FileSystemDataGrid组件的directory属性上。

因此,FileSystemComboBox组件与FileSystemDataGrid组件的路径是同步的。一旦FileSystemDataGrid组件的路径变化了,FileSystemComboBox组件的路径也变化。当FileSystemComboBox组件选择了其他路径,需要同步FileSystemDataGrid组件的路径。此时添加directorychange事件,在事件处理代码中作同步处理。

示例2.14代码如下:

<?xml version="1.0" encoding="utf-8"?>

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>

<![CDATA[

      import flash.filesystem.File; //引用File

]]>

</mx:Script>

    <mx:Panel width="800" height="600">

      <mx:VBox>

       <mx:HBox>

           <!--添加“FileSystemComboBox”组件,用以显示和选择文件目录-->

       <mx:FileSystemComboBox id="filecmb" directory="{filedg.directory}" directoryChange="filedg.directory=filecmb.directory;"/>

           <!--添加“Button”组件,单击按钮实现后退功能-->

           <mx:Button id="btnBack" label="后退" click="filedg.directory=filedg.directory.parent"/>

       </mx:HBox>

       <!--添加“FileSystemDataGrid”组件,用以显示文件列表-->

     <mx:FileSystemDataGrid id="filedg" width="100%" height="400" directory="{new File('c:/')}"/>

       </mx:VBox>

    </mx:Panel>

</mx:WindowedApplication>

“后退”按钮的功能是返回到上一级目录。File类中的parent属性表示上一级路径。 parent属性的返回值也为File类型;

以下代码中使用parent属性返回当前路径的上一级目录。

Var f:File=new File(“c:/windows”);

Var tf:File =  f.parent;

以下代码在单击“后退”按钮时FileSysternDataGrid组件返回上一级目录。

<s:Button id="btnBack" label="后退" click="filedg.directory=filedg.directory.parent"/>

 

按下【Ctr1+F 11 】组合键编译运行示例2.14。运行效果如图3.1.18所示。

 

3.1.18 文件系统组件

  

AIR中集成网页

Flex4AIR工程中新增了<mx:HTML>组件,用于支持嵌套网页。使用<mx:HTML>组件的语法如下。

<mx:HTML id=”” location=”网址” htmlText=”网页标题”/>

location属性表示当前的网址。对于绝对地址必须注明“http://",对于相对地址可省略修改location属性会自动触发<mx:HTML>组件重新加载新网址。htmlText属性表网页的标题。

简单的浏览器可以以<mx:HTML>组件为基础。根据输入框中的网址,修改<mx:HTML>组件的location属性即可。

示例2.15 实现了一个简单的浏览器。

<?xml version="1.0" encoding="utf-8"?>

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>

<![CDATA[

   

    

    import mx.controls.Alert; //引用Alert

private function gotoURL():void

{

html.location="http://"+txtURL.text; //改变html组件的链接地址

}

private function showLinks(event:Event):void

{


                //获得标签名为“a”的数据存于Object类型中,html标签中“a”表示链接

                var links:Object = this.html.htmlLoader.window.document.getElementsByTagName("A");;

                var s:String="";

                for(var i:Number = 0; i < links.length; i++)

{

  //获得链接地址存于字符串类型中

                  s+=links[i].getAttribute("href");

                  s+="\n";

             }

             //显示全部链接地址

             Alert.show(s);

          }

]]>

</mx:Script>

<mx:Panel id="panel" width="800" height="600">

   <mx:VBox width="100%">

    <mx:HBox width="100%"  backgroundColor="#DDFADD" height="30" verticalAlign="middle">

        <!--“mx:Spacer”标签是空格组件,可定义宽度和高度-->

        <mx:Spacer width="100%"/>

            <!--网址输入框-->

     <mx:TextInput id="txtURL" width="400"  x="{(panel.width-txtURL.width)/2}" />

     <!--“转到按钮,实现网页跳转-->

     <mx:Button id="btnTo" label="转到" click="gotoURL()"/>

     <mx:Spacer width="100%"/>

    </mx:HBox>

    <!--“mx:HTML”组件使得AIR程序可集成网页-->

<mx:HTML id="html" width="800" height="600" location="http://www.google.cn" complete="showLinks(event);"/>

   </mx:VBox>

</mx:Panel>

</mx:WindowedApplication>

 

 

输入框组件中x属性为“{(panel1.width-txtURL.width)/2 }”,保证输入框在Panel组件

中居中显示。

Complete事件触发的事件类型为Event,Event类中的currentTarget属性指明当前的目标组件,即为<mx:HTML>组件。通过htmlLoader.window.document即可取得html页面中的dom对象。

按下【Ctr1+F11】组合键编译运行示例2.15。运行效果如图3.1.19所示。

 

3.1.19 AIR中嵌入网页

1.5 JavaScriptActionScript3.0的交互

    ActionScript3.0JavaScript同为客户端开发技术。最大的不同在于ActionScript3.0语言运行于FlashPlayer中,JavaScript语言运行于浏览器中。JavaScript语言是流行己久的网络语言,功能强大、参考代码丰富。本小节将介绍JavaScriptActionScript3.0如何进行交互。

ActionScript3.0调用Javacript

   ActionScript3.0调用JavaScriptt使用ExternalInterface类的call()方法。ExternalInterface类在"flash.external.*”包中。ActionScript3.0调用JavaScript的语法如下。

   ExternalInterface .call(JavaScript函数名,参数1,参数2….);

 参数根据JavaScript函数中定义的数量及类型赋值。

 以下代码调用JavaScript函数t,此函数无参数,返回值为字符串型。

      var s:String= ExternalInterface.call(t);

 

示例:2.16演示了ExternalInterface的用法。

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  layout="absolute">

    <mx:Script>

     <![CDATA[

     import flash.external.ExternalInterface; //引用ExternalInterface

     public function invokeJavaScript():void

     {

       //调用JavaScript中的“returnTheName”函数

       lblResult.text=ExternalInterface.call("returnTheName",txtName.text);

     }

     ]]>

    </mx:Script>

   <mx:Panel  width="245" height="130" title="ActionScript调用JavaScript">

      <mx:TextInput id="txtName" text="[请输入名字]"/>

      <mx:Button id="btnConnect" label="确定" click="invokeJavaScript()" x="229" y="204"/>

  <mx:Label id="lblResult" text="test" x="205" y="99" width="150" height="80"/>

   </mx:Panel>

</mx:Application>

 

JavaScript调用ActionScript3.0

    JavaScript中调用ActionScript3.0之前,需要声明ActionScript3.0函数可调用。方法是使用ExternalInterface类的addCallback()方法。

   JavaScriptActionScript3.0中的函数名允许不一致。例如,ActionScript3.0中定义了一

个名为"compute”的函数,在JavaScript中调用此函数可使用其他函数名,如“c”、"com"

等。但需要在addCallback()方法中指明。

  示例 2.17 

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  layout="absolute" creationComplete="initApp()">

<mx:Script>

<![CDATA[

import flash.external.ExternalInterface; //引用ExternelInterface

//add函数计算从1加到100,并返回结果

public function add():int

{

  var i:int;

  var sum:int=0;

  for(i=1;i<=100;i++)

  {

    sum+=i;

  }

  return sum;

}

public function initApp():void

{

  //声明函数名

  ExternalInterface.addCallback("addTo100",add);

}

]]>

</mx:Script>

</mx:Application>

 

 

 

 

任务实训部分 


实训任务1Tree组件的应用

训练技能点

Tree组件节点的动态删除和添加。

需求说明

创建Flex应用程序,用户通过删除按钮和输入框进行树节点的删除和添加。

实现思路

(1)创建MXML应用程序,并设计功能界面。

<?xml version="1.0"?>

 

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx">

<s:layout>

<s:VerticalLayout/>

</s:layout>


<fx:Script>

<![CDATA[

import mx.collections.XMLListCollection;


[Bindable]

private var company:XML =

<list>

  <department title="Finance" code="200">

  <employee name="John H"/>

  <employee name="Sam K"/>

  </department>

  <department title="Operations" code="400">

  <employee name="Bill C"/>

  <employee name="Jill W"/>

  </department>                    

  <department title="Engineering" code="300">

  <employee name="Erin M"/>

  <employee name="Ann B"/>

  </department>                                

</list>;



private var companyData:XMLListCollection =

new XMLListCollection(company.department);


private function treeLabel(item:Object):String {

var node:XML = XML(item);

if( node.localName() == "department" )

return node.@title;

else

return node.@name;

}





]]>

</fx:Script>


<mx:Tree id="tree"

 top="72" left="50"

 dataProvider="{companyData}"

 labelFunction="treeLabel"

 height="225" width="300"/>


<mx:VBox>

<mx:HBox>           

<mx:Button label="Add Operations Employee"/>

<mx:TextInput id="empName"/>            

</mx:HBox>

<mx:Button label="Remove Selected Employee" />                     

</mx:VBox>

</s:Application>

 

2)为删除按钮和添加按钮添加事件处理代码。

<?xml version="1.0"?>

 

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx">

<s:layout>

<s:VerticalLayout/>

</s:layout>


<fx:Script>

<![CDATA[

import mx.collections.XMLListCollection;


[Bindable]

private var company:XML =

<list>

  <department title="Finance" code="200">

  <employee name="John H"/>

  <employee name="Sam K"/>

  </department>

  <department title="Operations" code="400">

  <employee name="Bill C"/>

  <employee name="Jill W"/>

  </department>                    

  <department title="Engineering" code="300">

  <employee name="Erin M"/>

  <employee name="Ann B"/>

  </department>                                

</list>;



private var companyData:XMLListCollection =

new XMLListCollection(company.department);


private function treeLabel(item:Object):String {

var node:XML = XML(item);

if( node.localName() == "department" )

return node.@title;

else

return node.@name;

}


private function addEmployee():void {

var newNode:XML = <employee/>;

newNode.@name = empName.text;

var dept:XMLList =company.department.(@title == "Operations");

if( dept.length() > 0 ) {

dept[0].appendChild(newNode);

empName.text = "";

}

}


private function removeEmployee():void {

var node:XML = XML(tree.selectedItem);

if( node == null ) return;

if( node.localName() != "employee" ) return;


var children:XMLList = XMLList(node.parent()).children();

for(var i:Number=0; i < children.length(); i++) {

if( children[i].@name == node.@name ) {

delete children[i];

}

}

}

]]>

</fx:Script>


<mx:Tree id="tree"

 top="72" left="50"

 dataProvider="{companyData}"

 labelFunction="treeLabel"

 height="225" width="300"/>


<mx:VBox>

<mx:HBox>           

<mx:Button label="Add Operations Employee" click="addEmployee();"/>

<mx:TextInput id="empName"/>            

</mx:HBox>

<mx:Button label="Remove Selected Employee" click="removeEmployee();"/>                     

</mx:VBox>

</s:Application>

3)运行此应用 效果如图 3.2.1所示。

 

  3.2.1 动态添加删除树接电脑

实训任务2:动态创建菜单

训练技能点

菜单的show方法。

需求说明

用户单击开始按钮,弹出菜单 模拟Windows的开始菜单。

实现思路

<?xml version="1.0"?>

 

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx" >

 

    <fx:Script>

        <![CDATA[

            // Import the Menu control.

            import mx.controls.Menu;

 

            // Create and display the Menu control.

            private function createAndShow():void {

                var myMenu:Menu = Menu.createMenu(null, myMenuData, false);

                myMenu.labelField="@label";

                myMenu.show(10, 10);

            }

        ]]>

    </fx:Script>

 

    <fx:Declarations>

        <fx:XML format="e4x" id="myMenuData">

            <root>

                <menuitem label="MenuItem A" >

                    <menuitem label="SubMenuItem A-1" enabled="false"/>

                    <menuitem label="SubMenuItem A-2"/>

                </menuitem>

                <menuitem label="MenuItem B" type="check" toggled="true"/>

                <menuitem label="MenuItem C" type="check" toggled="false"/>

                <menuitem type="separator"/>     

                <menuitem label="MenuItem D" >

                    <menuitem label="SubMenuItem D-1" type="radio"

                        groupName="one"/>

                    <menuitem label="SubMenuItem D-2" type="radio"

                        groupName="one" toggled="true"/>

                    <menuitem label="SubMenuItem D-3" type="radio"

                        groupName="one"/>

                </menuitem>

            </root>

        </fx:XML>

    </fx:Declarations>

 

    <mx:VBox>

        <mx:Button id="myButton"

            label="Open Menu"

            click="createAndShow();"/>

    </mx:VBox>

</s:Application>

运行应用,效果如图3.2.2所示。

 

3.2.2 菜单控件的show方法

 

实训任务3:创建简单的相册浏览器

训练技能点

使用组件处理数据和交互。

需求说明

使用FlexSWFLoader组件制作简易的相册浏览器,SWFLoader组件可以加载swf,jpg,png,等格式的文件其重要属性如下:

(1)source :要加载的目标路径。

(2)autoLoad:在指定了source后,是否自动加载目标对象,如果为false 那么还需要调用load方法才能加载目标。

(3)scaleContent:指示在加载对象后,是否缩放组件的尺寸来适应图片的大小,为false的时候则不缩放。

实现思路:

(1)创建MXML应用程序,设计浏览器界面。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Declarations>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

</fx:Declarations>

<s:Panel width="633" height="441" title="相册浏览器" horizontalCenter="0" verticalCenter="0">

<mx:HDividedBox width="100%" height="100%">

<mx:Tree width="30%" height="379"/>

<mx:SWFLoader width="70%" height="377" id="myLoader"  autoLoad="true" scaleContent="false"/>

</mx:HDividedBox>

<s:Rect left="0" right="0" bottom="0" height="30">

<s:fill>

<s:SolidColor color="#e2edf7"/>

</s:fill>

</s:Rect>

<s:Button id="btn" x="557" y="383" label="退出"/>

</s:Panel>

</s:Application>

 

2)编写功能代码。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.events.ListEvent;

 

protected function tree1_changeHandler(event:ListEvent):void

{

//获取用户选择的节点

var selectNode:Object = event.target.selectedItem;

//判断节点中是否包含src属性

if(selectNode.hasOwnProperty('@src')){



var nodeValue:String = selectNode.@src;

this.myLoader.source=nodeValue;


}

else{

//否则将loader图片清空

this.myLoader.source= null;

}

}

 

]]>

</fx:Script>

<fx:Declarations>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

<fx:XMLList id="treeData" >

<root title="相册分类">

<node title="卡通">

<node title="忍者神龟" src="images/1.jpg"></node>

<node title="公主小天使" src="images/2.jpg"></node>

<node title="变形金刚" src="images/3.jpg"></node>

</node>

<node title="风景">

<node title="天空" src="images/4.jpg"></node>

<node title="流水" src="images/5.jpg"></node>


</node>

</root>

</fx:XMLList>

</fx:Declarations>

<s:Panel width="633" height="441" title="相册浏览器" horizontalCenter="0" verticalCenter="0">

<mx:HDividedBox width="100%" height="100%">

<mx:Tree width="30%" height="379" dataProvider="{treeData}" labelField="@title" change="tree1_changeHandler(event)"/>

<mx:SWFLoader width="70%" height="377" id="myLoader"  autoLoad="true" scaleContent="false"/>

</mx:HDividedBox>

<s:Rect left="0" right="0" bottom="0" height="30">

<s:fill>

<s:SolidColor color="#e2edf7"/>

</s:fill>

</s:Rect>

<s:Button id="btn" x="557" y="383" label="退出"/>

</s:Panel>

</s:Application>

 

运行应用程序,效果如图3.2.3所示。

 

3.2.3 图片浏览器

 

实训任务4:实现简易记事本

训练技能点

Ø AIR程序的创建。

Ø AIRio的应用。

需求说明

实现简易的记事本程序,可以打开文本文件 修改  和创建。

实现步骤:

(1)创建AIR应用程序,设计记事本界面。

<?xml version="1.0" encoding="utf-8"?>

<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" title="记事本">




<fx:Declarations>

<fx:XMLList id="item">

<menu label="文件">

<item label="新建"></item>

<item label="打开"></item>

<item label="保存"></item>

<item label="另存为..."></item>

</menu>

<menu label="编码设置">

<item label="ANSI"></item>

<item label="UTF-8"></item>


</menu>


</fx:XMLList>

</fx:Declarations>

<mx:TextArea id="fileTextArea"

 top="25" left="0" right="0" bottom="0"

 fontFamily="Arial"

 fontSize="20"

 />


<mx:MenuBar id="myMenuBar" labelField="@label" dataProvider="{item}"


fontSize="14" height="26" left="0" right="0" >





</mx:MenuBar>

</s:WindowedApplication>

(2)为菜单的change事件添加处理代码 完成功能。

<?xml version="1.0" encoding="utf-8"?>

<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" title="记事本">

<fx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.events.MenuEvent;

private var change:Boolean = false;

private var  file:File = new File();

protected function myMenuBar_itemClickHandler(event:MenuEvent):void

{

var str:String =event.label;

switch (str){

case "新建":

newfile();

break;

case "打开":

open();

break;

case "保存":

save();

break;

case "另存为...":

newfile();

break;


}

}

protected function newfile():void{

if(change){

save();

}

this.fileTextArea.text="";

}

protected function save():void{

file =new File();


file.browseForSave("save file");

file.addEventListener(Event.SELECT,write);


}

protected function write(event:Event):void{

var fs:FileStream = new FileStream();

fs.open(file,FileMode.WRITE);


fs.writeMultiByte(this.fileTextArea.text,"ANSI");

fs.close();

}


protected function open():void{


var filter1 : FileFilter = new FileFilter("text","*.txt;*.html;*.mxml;");

var filter2 : FileFilter = new FileFilter("所有文件","*.*");

file.browseForOpen("open file",[filter1,filter2]);

file.addEventListener(Event.SELECT,readFile);

}


protected function readFile(event:Event):void{

var fs:FileStream = new FileStream();

fs.open(file,FileMode.READ);

Alert.show(fs.bytesAvailable.toString());

var content:String=fs.readMultiByte(fs.bytesAvailable,"ANSI");

// fs.bytesAvailable是读取进来的字节数字 即length

this.fileTextArea.text  = content;

fs.close();

}


]]>

</fx:Script>



<fx:Declarations>

<fx:XMLList id="item">

<menu label="文件">

<item label="新建"></item>

<item label="打开"></item>

<item label="保存"></item>

<item label="另存为..."></item>

</menu>

<menu label="编码设置">

<item label="ANSI"></item>

<item label="UTF-8"></item>


</menu>


</fx:XMLList>

</fx:Declarations>

<mx:TextArea id="fileTextArea"

 top="25" left="0" right="0" bottom="0"

 fontFamily="Arial"

 fontSize="20"

 />


<mx:MenuBar id="myMenuBar" labelField="@label" dataProvider="{item}"


fontSize="14" height="26" left="0" right="0" itemClick="myMenuBar_itemClickHandler(event)">





</mx:MenuBar>

</s:WindowedApplication>

3)运行应用程序,效果如图3.2.4所示。

 

3.2.4 记事本

 

 

 

 

 

 

 

 

 

巩固练习


选择题

1. 以下不属于RIA概念的是 ()

A. RIA将桌面应用程序的强交互性与传统的WEB应用的灵活性综合起来。

B. RIA的富客户端采用异步的方式和服务器进行交互。

C. RIA可以整合声音 视频等桌面元素。

D. RIA通信中会传输所有数据,加重了数据传输负担。

2. 以下关于Flex程序的说法,正确的是 ()

A. Flex程序由*.MXML *.as  *.css文件组成。

B. MXML语言专用于Flex程序中,是用于描述界面表现的一种XML标记语言。

C. ActionScript 是针对Adobe Flash Player运行环境的编程语言。

D. MXML提供了一系列标签供用户使用,MXML不区分大小写。

3. 以下关于Application布局的说法,正确的是()

A. Application默认布局是BasicLayout

B. HorizontalLayout 表示水平布局。

C. VerticalLayout表示竖直布局。

D. Tilelayout表示主题布局方式。

4. 关于以下代码的说法,正确的是()

<mx: StringValidator source="{txtpwd}" proerty="text" trigger="{submit}" triggerEvent="click"/>

A. 当用户单击提交按钮的时候,触发验证对象。

B. 当用户单击idsubmit的按钮,触发验证对象。

C. 验证对象验证的目的是idtxtpwd的组件。

D. 验证对象验证的属性是txtpwdtext属性。


Flex常用组件()

学习内容

Ø 视图状态

Ø Flex页面间跳转

Ø Flex应用模态窗体

Ø 数据绑定

Ø 使用拖拽

Ø 图表

能力目标

Ø 掌握并应用视图状态来开发Flex应用程序

Ø 掌握在Flex应用中实现页面间的跳转

Ø 理解数据绑定

Ø 掌握拖放和图表的使用

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本章简介

上一章讲解了Flex组件的分类和常用组件等知识。本章将学习视图状态、Flex页面间的跳转、Flex应用的模态窗体、数据绑定、使用拖放和Flex图表等知识。在程序中,ActionScript可以将界面分割成相对独立的部分,用于表示不同的功能,显示当前程序的运行状态,每个界面是一个状态。在开发Web应用时,经常根据业务需求进行页面间的跳转。

Flex应用中,可以通过Extemallnterface类的静态方法call实现页面跳转。在Web应用开发中.经常使用模态窗体减少页面的跳转。Flex中通过PopUpManager类实现弹出模态窗体。使用数据绑定时,当数据源对象的数据发生变化时,目标对象的数据会自动更新,不需要再编写代码强制更新。另外本章还介绍了使用Flex图表来展现数据。

核心技能部分


2.1 视图状态

Flex程序中引入了状态设计的概念。在程序中,按照功能的需求,将界面分割成相对独立的部分。在运行过程巾,随蓿用户的交互,界面在各个部分之间切换。例如,在购物车程序中,登录界面、选购商品界面、购物车界面、付款界面代表着不同的功能,显示当前程序的运行状态.每个界面就是一个状态。 

使用状态应该首先定义一个默认的状态,然后在此基础上重写或更改,从而形成一系列其他样式。可以通过状态添加、移除某些子元素,更改CSS或者属性的值,更改触发的事件。例如,在典型的登录页面巾,用户单击注册按钮时会生成注册界面(不是新页面)。此时,通过浏览器的后退按钮不能回到原来的状态。 

2.1.1 视图状态工作原理

定义状态

<states>标签用于为用户定义状态,但为状态添加子元素和设置属性的操作不在此处进行。例如, 定义loginreg两种状态的代码如下: 

<s : states>

<s : State name=”login”/>

<s : State name=”reg”/> 

</s : states>

改变状态

可以通过改变组件的currentState属性值更改状态,该属性的默认值是定第一个状态。

<s:Button id=”but1” click=”currentState=’reg’”/>

<s:Button id=”but2” click=”currentState=’login’”/>

上述代码表示单击but1按钮时,当前的视图状态变成“reg”;肖单击but2按钮时,当前视图状态变成login 

为状态设定属性、样式和事件

设定一个组件属于禁个状态的属性值,代码如下: 

<sButton label=¨登录¨ label.reg=¨注册">

上述代码表示该按钮的lable值在“reg”状态下值为注册,在其他状态下值为登录 

添加或移除组件

通过属性includelnexcludeFrom可以向状态中添加或移除组件。includeln表示该组件将被添加到属性值所指的状态,excludeFrom表示该组件将从属性值所指的状态中删除。 

<s:Label text="确认密码: " includeIn="reg"/>

<s:TextInput height="19" includeIn="reg"/>

上述代码表示只有当前视网状态为“reg”状态时,Label组件和Textlnput组件才会显示。其他状态均会隐藏。 

示例4.1演示了视图状态的应用。

<?xml version="1.0" encoding="utf-8"?>

 

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    xmlns:s="library://ns.adobe.com/flex/spark"

    >

   

<s:states>

<s:State name="Login"/>    

<s:State name="Register"/>

</s:states>

<s:Panel

 title="Login" title.Register="Register" horizontalCenter.Login="0" verticalCenter.Login="0">


<mx:Form id="loginForm">

<mx:FormItem label="Username:">

<s:TextInput/>

</mx:FormItem>

<mx:FormItem label="Password:">

<s:TextInput/>

</mx:FormItem>

<mx:FormItem id="confirm" label="Confirm:" includeIn="Register">

<s:TextInput/>

</mx:FormItem>            

<mx:FormItem>            

<s:HGroup>

<mx:LinkButton id="registerLink"

   includeIn="Login"

   label="Need to Register?"

   click="currentState='Register'"/>

<mx:LinkButton label="Return to Login"

   includeIn="Register"

   click="currentState=''"/>

<mx:Spacer width="100%" id="spacer1"/>

<s:Button id="loginButton"

  label="Login" label.Register="Register" />

</s:HGroup>

</mx:FormItem>            

</mx:Form>

</s:Panel>

</s:Application>

运行实例4.1效果如图4.1.1所示:

 

4.1.1 视图状态示例

在图4.1.1中点击Need Register按钮,将显示另一个状态,如图4.1.2所示:

 

4.1.2 视图状态示例

 

状态如果结合渲染器来使用就更为方便。渲染器产生的每个选项都会有鼠标悬停和选中等状态,会自动触发而改变状态,示例4.2演示了渲染器和状态的结合使用:

 

构建主界面:

<?xml version="1.0"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout>

        <s:VerticalLayout horizontalAlign="center"/>

    </s:layout>

    

    <s:DataGroup itemRenderer="myComponents.ImageComp"

        width="300" height="400">

        <s:layout>

            <s:TileLayout columnWidth="150" rowHeight="175"

                requestedColumnCount="2" requestedRowCount="2" />

        </s:layout>

        <mx:ArrayCollection>

            <fx:Object

                name="Nokia 3595"

                data="1"

                price="129.99"

                image="assets/a.jpg"

                description="Kids love it."/>

            <fx:Object

                name= "Nokia 3650"

                data="1"

                price="99.99"

                image="assets/b.jpg"

                description="Impress your friends."/>

            <fx:Object

                name="Nokia 6010"

                data="1"

                price="49.99"

                image="assets/c.jpg"

                description="Good for everyone."/>

            <fx:Object

                name="Nokia 6360"

                data="1"

                price="19.99"

                image="assets/d.jpg"

                description="Great deal!"/>

        </mx:ArrayCollection>

    </s:DataGroup>

</s:Application>

定义渲染器:

<?xml version="1.0" encoding="utf-8"?>

<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout>

        <s:VerticalLayout/>

    </s:layout>

 

    <s:states>

        <s:State name="normal"/>

        <s:State name="hovered"/>

        <s:State name="selected"/>

    </s:states>     

 

    <mx:Image id="img1"

        source="{data.image}"

        width="75" width.hovered="85"

        height="75" height.hovered="85"/>

    <s:Label text="{data.name}"

        color="blue"

        fontSize.hovered="16"/>

    <s:Label text.hovered="{data.price}"/>

    <s:TextArea id="t1"

        visible="false" visible.hovered="true"

        height="30" width="125"

        text.hovered="{data.description}"/>

</s:ItemRenderer>

 

运行应用效果如图4.1.3所示:

 

4.1.3 视图状态示例

2.1.2 为状态过渡添加动画效果

Transition的使用极大地增强了状态模式下界面的表现力。Transition对象位于mx.states包中,包括fromStatetoState两个属性,分别代表过渡动作的前后状态。当状态切换符合Transition的条件,即切换前后的状态与fromStatetoState都相等时,动画效果就开始播放。当fromStatetoState取值为“*” 时,表示无条件限制,即只要有状态切换就产生动画效果。修改示例4.2中的代码,向其中添加状态过渡的淡入淡出效果。 

<?xml version="1.0" encoding="utf-8"?>

<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout>

        <s:VerticalLayout/>

    </s:layout>

 

    <s:states>

        <s:State name="normal"/>

        <s:State name="hovered"/>

        <s:State name="selected"/>

    </s:states>     

<s:transitions>

<s:Transition>

<s:Fade target="{img1}" alphaFrom="0" alphaTo="1" duration="3000"/>

</s:Transition>

</s:transitions>

 

<mx:Image id="img1"

        source="{data.image}"

        width="75" width.hovered="85"

        height="75" height.hovered="85"/>

    <s:Label text="{data.name}"

        color="blue"

        fontSize.hovered="16"/>

    <s:Label text.hovered="{data.price}"/>

    <s:TextArea id="t1"

        visible="false" visible.hovered="true"

        height="30" width="125"

        text.hovered="{data.description}"/>

</s:ItemRenderer>

再次运行应用,当鼠标移动到图片上.应用会缓缓地以淡入淡出的效果显示。

2.2 Flex页面间的跳转

在开发Web应用时,经常根据业务需求进行页面间的跳转。在Flex应用中,可以通过ExternalInterface类的静态方法call实现页面跳转。Extemallnterface类被称为FlexJavaScript之间的通讯类。 

示例4.2

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:mx="library://ns.adobe.com/flex/mx"

   xmlns:s="library://ns.adobe.com/flex/spark">

 


<fx:Script>

<![CDATA[

import mx.controls.Alert;

 

protected function btnLogin_clickHandler(event:MouseEvent):void {

var uid:String=this.txtUid. text;//获取用户输入的用户名

var pwd:String=this.txtPwd.text;//获取用户输入的密码

if (uid=="scce"&&pwd=="8888") {

//如果登录成功.则跳转到主页面

ExternalInterface.call("function(){ window.location='App.html';}");

}

else {

Alert.show("登录失败","页面间跳转演示");

}

}

 

]]>

</fx:Script>

<s:Panel x="51" y="44" title="登录 "

verticalCenter="0" width=" 354 " height="182 " defaultButton=" { btnLogin } "

 horizontalCenter="0">

<s:Rect left="0" right="0" bottom="0" height="30">

<s:fill>

<s:SolidColor color= "#E2EDF7"/>

</s:fill>

</s:Rect>

<s:Button id="btnLogin" x="179" y="123" label="登录 " click="btnLogin_clickHandler(event)" />

<s:Button x="273" y="123" label="退出 "/>

<s:Label x="112" y="45" text="用户名: " width="51"/><s:TextInput id="txtUid" x="167" y="40"/>

<s:Label x="112" y="80" text="密 码: " width="51"/>

<s:TextInput id="txtPwd" x="167" y="75" displayAsPassword="true"/>

<mx:Image x="20" y="10" source="img/login.gif" scaleContent="false" width="44" height="40"/>

</s:Panel>

</s:Application>

在示例4.3中,通过一个登录页面对用户输入的用户名和密码进行判断,如果成功则跳转到主页面,运行效果如图4.1.4所示.

 

4.1.4 页面跳转示例

2.3 Flex应用中的模态窗体

Web应用开发中经常使用模态窗体,以减少页面的跳转。例如,父窗体显示RichTextEditor文本编辑控件, 在父窗体中有一个【查找/替换】,点击该按钮弹出模态窗体,用户可以通过窗体实现文本的查找和替换,如图4.1.5所示。

 

4.1.5 主窗口

在图4.1.5中,单击【查找/替换】按钮,弹出模态窗体,如图4.1.6所示。 

 

4.1.6 模态窗体

 

Flex中,通过PopUpManager类的两个静态方法弹出模态窗体。 

(1) createPopUp(parentclassNamemodel):用于创建一个弹出式模态窗体。参数说明如下: 

1) parent:指定弹出式模态窗体的父窗体,一般设为this,表示父窗体本身。 

2) className:指定弹出式模态窗体的类,该方法根据类来实例化模态窗体,其参数类型为

Class 

3) model:指定是否以模态窗体的形式弹出新窗体,true表示模态窗体,false表示非模态窗体。 

(2) centerPopUp(popUP):用于将已创建的模态窗体的实例在父窗体的中间位置弹出,参数popUp指定创建好的模态窗体的实例。 

示例4.4

 (1)定义模态窗体组件。 

<?xml version="1.0"?>

 

<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"

title="Find/Replace"

showCloseButton="true"

close="closeDialog();"

>

<mx:Script>

<![CDATA[

import mx.controls.TextArea;

import mx.managers.PopUpManager;

public var RTETextArea:TextArea;


public function replaceAndClose():void{

RTETextArea.text = RTETextArea.text.replace(ti1.text, ti2.text);

PopUpManager.removePopUp(this);

}

public function closeDialog():void {

PopUpManager.removePopUp(this);

}

]]>

</mx:Script>


<mx:Label text="Find what:"/>

<mx:TextInput id="ti1"/>

<mx:Label text="Replace with:"/>

<mx:TextInput id="ti2"/>

<mx:Button label="Replace" click="replaceAndClose();"/>

</mx:TitleWindow>

 

2)创建父窗体,并添加弹出代码:

<?xml version="1.0"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>

<![CDATA[

import mx.controls.*;

import mx.containers.*;

import flash.events.*;

import mx.managers.PopUpManager;

import mx.core.IFlexDisplayObject;

public var w:IFlexDisplayObject;


public function addFindReplaceButton():void {

var but:Button = new Button();

but.label = "Find/Replace";

but.addEventListener("click",findReplaceDialog);

rt.toolbar.addChild(but);

}


public function findReplaceDialog(event:Event):void {

var w:MyTitleWindow = MyTitleWindow(

PopUpManager.createPopUp(this, MyTitleWindow, true)

);

w.height=200;

w.width=340;


w.RTETextArea = rt.textArea;

PopUpManager.centerPopUp(w);

}

]]>

</mx:Script>

<mx:RichTextEditor id="rt" width="95%"

   title="RichTextEditor"

   text="This is a short sentence."

   initialize="addFindReplaceButton();"

   />

</mx:Application>

2.4 数据绑定

2.4.1 数据绑定的概念

使用数据绑定时Flex会自动将一个对象的数据复制,提供给另一个对象使用。其中,提供数据的一方称为数据源对象,使用数据的一方称为目标对象。当数据源对象的数据发生变化时,目标对象的数据会自动更新,不需要再编写代码来强制更新。实际上,绑定的实现也借助于事件机制完成。当对目标使用的数据绑定后,目标对象就会侦听数据源对象的某一固定事件。在随后的到程中.当源对象的数据变化时,数据源会派发改变事件( ChangeEvent),通知目标对象更新最新的数据。整个事件流过程都由Flex完成。 

2.4.2 简单的数据绑定

MXML代码中,使用大括号“{}”是实现数据绑定的最快捷方式。只要将源数据对象放在大 括号中,将其作为目标对象的值即可。 

示例4.5

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:mx="library://ns.adobe.com/flex/mx"

   xmlns:s="library://ns.adobe.com/flex/spark">

 

<s:Panel x="98" y="75" width="382" height="276" title="数据绑定示例演示 ">

<s:Rect left="0" top="0" bottom="30" right="0">

<s:fill>

<s:SolidColor color="{myCp.selectedColor}"/>

</s:fill>

</s:Rect>

<s:Rect left="0" bottom="0" right="0" height="30">

<s:fill>  

<s:SolidColor color="#E2EDF7"/>

</s:fill>

</s:Rect>

<mx:ColorPicker id='myCp' x="8" y="218"/>

</s:Panel>

</s:Application>

在示例4.5中,使用ColorPicker组件的值作为Rect的背景色,运行结果如图4.1.7所示。

 

4.1.7数据绑定演示

当颜色组件选择不同的颜色时,Rect中的背景色也会随之变化。 

2.4.3 函数数据绑定

在实际开发中,可以根据需要将处理的代码写在一个函数中,在绑定表达式中直接调用该函数。

示例4.6

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<fx:Script>

<![CDATA[

//定义用于根据下拉框返回Image组件Source的函数

private function getPic (picIndex:int):String {

//定义变量用于保存图片路径

var picPath:String;

switch (picIndex) {

case 0:

picPath="img/1.jpg";

break;

case 1:

picPath="img/2.jpg";

break;

case 2:

picPath="img/3.jpg";

 break;

}

return picPath;

}

]]>

</fx:Script>

<fx:Declarations>

<s:ArrayCollection id="picArr">

<fx:String>第一张图片</fx:String>

<fx:String>第二张图片</fx:String>

<fx:String>第三张图片</fx:String>

</s:ArrayCollection>

</fx:Declarations>

<s:Panel x="51" y="44" width="470" height="361" title="Flex函数数据绑定示例演示">

<s:Rect left="0" right="0" bottom="0" height="30">

<s:fill>

<s:SolidColor color="#E2EDF7"/>

</s:fill>

</s:Rect>

<mx:Image id="img" source="{getPic(this.ddlPic.selectedIndex)}" left="0" top="0" right="0" bottom="30" scaleContent="false" />

<s:DropDownList id="ddlPic" x="6" y="303" dataProvider=" { picArr } " selectedIndex="0"/>

</s:Panel>

</s:Application>

 

运行示例4.6,随着ddIPicselectedIndex属性值改变,Image组件的source属性会依据函壹getPic返回值的变化而变化,结果如图4.1.8所示。 

 

 

4.1.8 使用函数进行绑定

另外使某个变量参与绑定,只要在定义变量的时候加上特性[Bindable]即可,以下代码将ShopList参与绑定:

[Bindable]

Public var shopList:ShopList;

2.5 使用拖放

在桌面应用程序中,拖放是一种常见的用户界面技术。在web应用程序中,在实现了RIA后,拖放才成为一种常见技术,在Flex应用中,利用拖放操作管理器(Drag and Drop Manager)及其提供的工具实现拖放。拖放操作包含三个操作:

1)初始化:用户单击某个Flex组件或者某个Flex组件中的条目,按下鼠标的时候同时移动单击的组件或项目。该组件或项目称为拖曳初始器。 

2)拖曳:按下鼠标的同时,用户可以在屏幕中移动鼠标。Flex会显示一张拖曳代理的图片。 

3)释放:当用户将鼠标移动到允许释放数据的组件上时,可以将项目放置在释放目标上。 

2.5.1 在两个AdvancedDataGrid之间拖放

在两个AdvancedDataGrid之间实现拖放的步骤如下: 

(1)在源AdvancedDataGrid(命名为adgFrom)中将dropEnabled属性设置为true,使adgFrom支持拖拽。

(2)在目标AdvancedDataGrid(命名为adgTarget)中将dropEnabled设置为true,使adgTarget能够接受拖拽源。

3) 在<fx:script>块中,声明一个名为“adgTargetDp”的可绑定的私有变量,变量类型为Array Collection.并将该变量绑定到目标AdvancedDataGrid中的dataProvider属性中。

示例4.7

<?xml version="1.0"?>

<!-- dragdrop\SimpleDGToDGAlert.mxml -->

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    width="650"

    creationComplete="initApp();">

    <s:layout>

        <s:VerticalLayout/>

    </s:layout>

 

    <fx:Script>

        <![CDATA[        

            import mx.collections.ArrayCollection;

            import mx.controls.Alert;

            import mx.events.DragEvent;

            

            private function initApp():void {

              srcgrid.dataProvider =  new ArrayCollection([

                {Id:1,Artist:'Carole King', Album:'Tapestry', Price:11.99},

                {Id:2,Artist:'Paul Simon', Album:'Graceland', Price:10.99},

                {Id:3,Artist:'Original Cast', Album:'Camelot', Price:12.99},

                {Id:4,Artist:'The Beatles', Album:'The White Album', Price:11.99}

              ]);

                

                destgrid.dataProvider = new ArrayCollection([]);

            }

 

      

            public function dragDropHandler(event:DragEvent):void {    

              

                var dragObj:Object=

                    event.dragSource.dataForFormat("items")[0] ;

 

              

                var artistList:String='Artist: ' + dragObj.Artist;

             

                

                Alert.show(artistList);    


 

            }           

        ]]>

    </fx:Script>

 

    <s:HGroup>

        <s:VGroup>

            <s:Label text="Available Albums"/>

            <mx:AdvancedDataGrid id="srcgrid"

                allowMultipleSelection="true"

                dragEnabled="true"

                dropEnabled="true"

dragMoveEnabled="true"

              >                

                <mx:columns>

                    <mx:AdvancedDataGridColumn dataField="Artist"/>

                    <mx:AdvancedDataGridColumn dataField="Album"/>

                    <mx:AdvancedDataGridColumn dataField="Price"/>

                </mx:columns>    

            </mx:AdvancedDataGrid>

        </s:VGroup>

 

        <s:VGroup>

            <s:Label text="Buy These Albums"/>

<mx:AdvancedDataGrid id="destgrid"

                allowMultipleSelection="true"

                dragEnabled="true"

                dropEnabled="true"

                dragMoveEnabled="true"

            >                

                <mx:columns>

<mx:AdvancedDataGridColumn dataField="Artist"/>

<mx:AdvancedDataGridColumn dataField="Album"/>

<mx:AdvancedDataGridColumn dataField="Price"/>

                </mx:columns>    

           </mx:AdvancedDataGrid>

        </s:VGroup>

    </s:HGroup>

 

    <s:Button id="b1"

        label="Reset"

        click="initApp();"/>

</s:Application>

 

 

运行示例4.7中,在源AdvancedDataGrid中拖曳一行数据到目标AdvancedDataGrid中。目标AdvancedDataGrid会自动添加一行新数据,如图4.1.9所示。 

 

4.1.9 拖拽示例

以上代码中, “items”被用于作为格式的名称访问DragSource中的数据。TreeDataGridList Flex控件在自动创建一个DragSource时都使用“items”作为格式的名称。通过  event.dragSource.dataForFormat("items")即可取得拖拽的数据,其格式是Array

AdvancedDataGrid控件中dragMoveEnabled属性用来控制在拖拽后,该数据是否被删除。如果为true,则意味着拖拽后在原控件中删除该数据,如果保持默认或者设置为false,则还要采取措施放置数据的重复拖拽,改进示例4.7如下

<?xml version="1.0"?>

<!-- dragdrop\SimpleDGToDGAlert.mxml -->

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx"

    width="650"

    creationComplete="initApp();">

    <s:layout>

        <s:VerticalLayout/>

    </s:layout>

 

    <fx:Script>

        <![CDATA[        

            import mx.collections.ArrayCollection;

            import mx.controls.Alert;

            import mx.events.DragEvent;

            

            private function initApp():void {

              srcgrid.dataProvider =  new ArrayCollection([

                {Id:1,Artist:'Carole King', Album:'Tapestry', Price:11.99},

                {Id:2,Artist:'Paul Simon', Album:'Graceland', Price:10.99},

                {Id:3,Artist:'Original Cast', Album:'Camelot', Price:12.99},

                {Id:4,Artist:'The Beatles', Album:'The White Album', Price:11.99}

              ]);

                

                destgrid.dataProvider = new ArrayCollection([]);

            }

 

      

            public function dragDropHandler(event:DragEvent):void {    

              

                var dragObj:Object=

 event.dragSource.dataForFormat("items")[0] ;

 

              

                var artistList:String='Artist: ' + dragObj.Artist;

                

                

                Alert.show(artistList);    

for each (var v in  destgrid.dataProvider){


if(v.Id==dragObj.Id){

this.destgrid.dropEnabled=false;

}


}

 

            }           

 

protected function srcgrid_dragStartHandler(event:DragEvent):void

{

this.destgrid.dropEnabled=true;

}

 

        ]]>

    </fx:Script>

 

    <s:HGroup>

        <s:VGroup>

            <s:Label text="Available Albums"/>

            <mx:AdvancedDataGrid id="srcgrid"

                allowMultipleSelection="true"

                dragEnabled="true"

                dropEnabled="true"

dragStart="srcgrid_dragStartHandler(event)"

              >                

                <mx:columns>

                    <mx:AdvancedDataGridColumn dataField="Artist"/>

                    <mx:AdvancedDataGridColumn dataField="Album"/>

                    <mx:AdvancedDataGridColumn dataField="Price"/>

                </mx:columns>    

            </mx:AdvancedDataGrid>

        </s:VGroup>

 

        <s:VGroup>

            <s:Label text="Buy These Albums"/>

<mx:AdvancedDataGrid id="destgrid"

                allowMultipleSelection="true"

                dragEnabled="true"

                dropEnabled="true"

                dragMoveEnabled="true"

                dragDrop="dragDropHandler(event);">                

                <mx:columns>

<mx:AdvancedDataGridColumn dataField="Artist"/>

<mx:AdvancedDataGridColumn dataField="Album"/>

<mx:AdvancedDataGridColumn dataField="Price"/>

                </mx:columns>    

           </mx:AdvancedDataGrid>

        </s:VGroup>

    </s:HGroup>

 

    <s:Button id="b1"

        label="Reset"

        click="initApp();"/>

</s:Application>

2.5.2 在不可直接拖曳组件上实施拖放操作

在上一小节中,AdvancedDataGrid组件本身支持拖曳功能,在不支持拖曳功能的组件上开发自定义的拖曳功能时必须借助DragManager类,该类位于mx.managers包中,专用于管理拖曳事件,有两个重要的静态方法: 

(1) DragManager.doDrag:该方法包含3个重要参数。 

Ø  draglnitiator:用于指定拖曳事件的目标对象。 

Ø dragSource:指定拖曳事件的数据源,用于传递数据。 

Ø mouseEvent:鼠标事件对象,包含拖曳事件开始时的鼠标信息,如鼠标位置。 

(2) DragManager.acceptDragDrop:用于指定对象是否接受拖曳的数据,不接受则将无法在该对象上拖放。 

Panel中的Image组件拖曳到Panel中见示例4.8

<?xml version="1.0"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

    xmlns:s="library://ns.adobe.com/flex/spark"

    xmlns:mx="library://ns.adobe.com/flex/mx" >

    <s:layout>

        <s:HorizontalLayout/>

    </s:layout>

 

    <fx:Script>

        <![CDATA[

            import mx.managers.DragManager;

            import mx.core.DragSource;

            import mx.events.DragEvent;

            import flash.events.MouseEvent;

 

           

            [Embed(source='assets/bullet_green.png')]

            public var globeImage:Class;

 

            private function mouseOverHandler(event:MouseEvent):void

            {                

                var dragInitiator:Image=Image(event.currentTarget);

                var ds:DragSource = new DragSource();

                ds.addData(dragInitiator, "img");               

 

               

                var imageProxy:Image = new Image();

                imageProxy.source = globeImage;

                imageProxy.height=10;

                imageProxy.width=10;                

                DragManager.doDrag(dragInitiator, ds, event,

                    imageProxy, -15, -15, 1.00);

            }

            

          

            private function dragEnterHandler(event:DragEvent):void {

              if (event.dragSource.hasFormat("img"))

                DragManager.acceptDragDrop(Canvas(event.currentTarget));

            }

            

 

            private function dragOverHandler(event:DragEvent):void

            {

                if (event.dragSource.hasFormat("img")) {

                    if (event.ctrlKey) {                    

                        DragManager.showFeedback(DragManager.COPY);

                        return;

                    }

                    else {

                        DragManager.showFeedback(DragManager.MOVE);

                        return;

                    }

                }

 

                DragManager.showFeedback(DragManager.NONE);

            }

            

           

            private function dragDropHandler(event:DragEvent):void {

              if (event.dragSource.hasFormat("img")) {

                  var draggedImage:Image =

                    event.dragSource.dataForFormat('img') as Image;

                  var dropCanvas:Canvas = event.currentTarget as Canvas;

              

                 

                  var newImage:Image=new Image();

                  newImage.source = draggedImage.source;

                  newImage.x = dropCanvas.mouseX;

                  newImage.y = dropCanvas.mouseY;

                  dropCanvas.addChild(newImage);

              }

            }

     

            private function dragCompleteHandler(event:DragEvent):void {

                var draggedImage:Image =

                    event.dragInitiator as Image;

                var dragInitCanvas:Canvas =

                    event.dragInitiator.parent as Canvas;

 

                if (event.action == DragManager.MOVE)

                    dragInitCanvas.removeChild(draggedImage);

            }            

        ]]>

    </fx:Script>

 

    <mx:Canvas

        width="250" height="500"  

        borderStyle="solid"

        backgroundColor="#DDDDDD">

      

<mx:Image id="myimg"

            source="@Embed(source='assets/b.jpg')"

            mouseMove="mouseOverHandler(event);"

            dragComplete="dragCompleteHandler(event);"/>

    </mx:Canvas>

 

    <mx:Canvas

        width="250" height="500"  

        borderStyle="solid"

        backgroundColor="#DDDDDD"

        dragEnter="dragEnterHandler(event);"

        dragOver="dragOverHandler(event);"

        dragDrop="dragDropHandler(event);">        

    </mx:Canvas>

</s:Application>

运行示例4.8中的代码,拖动Image组件到Panel组件中,结果如图4.10所示,

 

4.10 在不可直接拖曳组件上实施拖放操作

2.6  Flex图表

2.6.1 Flex图表概述

  以图表或是图的方式显示数据的能力可以使得程序用户的数据交互更为容易。与仅显示简单的数字数据表不同,Flex可以显示条状图,饼图,线图或是其他类型的图表,并且可以使用颜色,标题以及二维图形来表示我们的数据。在这一部分我们会介绍Flex图表的使用。

数据表示可以使得我们简化数据表示与数据关系的方式来表示数据。图表是数据的一种类型,从而我们可以使用二维的图形来表示我们的数据。Flex支持最常见的二维图形,例如条状图,柱状图,饼图,并且提供给我们对于图表显示的的极大控制。
一个简单的图表显示单一的数据系列,在这里系列是一组相关的数据点。例如,一个数据系列也许是月度销售收益,或者是一天的旅馆占有率。图4.1.11显示了过去六个月的与销售收益相应的数据系列:


4.1.11 柱状图

图表也许会添加第二个数据系列。例如,我们也许会包含过去六个月的利润。图4.1.12显示了两个数据系列,一个是销售,一个是利润:


 4.1.12 柱状图

 


图表类型 
Flex支持最常见的一些图表类型,包括条状图,线图,饼图以及其他的类型。这一部分描述Flex所提供的图表集合。除了这些图表类型以外,我们还可以扩展笛卡尔图表控件还创建自定义的图表。


区域图表 
我们使用图表控件将数据表示为一个用与数据值相关的线来界定的区域。在线以下的区域用一种颜色或是一种类型来进行填充。我们可以用图标或是符号来表示线上的每一个数据点,或者是不使用图标而仅用单一的线。
 4.1.13是一个区域图表的例子:


 4.1.13 区域图表

 


条状图 
我们使用条状图控件来将数据表示为一系列的垂直条,垂直条的长度由数据值为决定。我们可以使用条状图控件来表示图表的多样性。
条状图实际上是柱状图顺时针旋转90度。所以条状图与柱状图有着许多同样的特性。


泡沫图 
我们使用泡沫图对于每一个数据点用三个值来表示数据:一个值决定他的X位置,一个值决定他的Y位置,而另一个值来决定图表符号图表上相对于其他数据点的尺寸。
<mx:BublleChart>标签还有一个额外的属性,maxRadius。这个属性以象素值指定了最大的图表元素的最大半径。与最大值相关的数据点赋值为这个半径值,而其他的数据点相对于最大值赋值为一个较小的半径值。默认值为30象素。
如图4.1.14 为一个泡沫图的例子:


4.1.14 泡沫图

 


烛台图表 
CandlestickChart控件将财经数据表示为一个系列的烛台,来表示数据系列的高,低,开放与关闭的值。烛台上每一个垂直线的最高点与最低点表示数据点的最大值与最小值,而整个盒的最高点与最低点代表数据的开放值与关闭值,每一个烛台的不同填充由数据点的关闭值是否高于或是低于开放值来决定。
如图4.1.15是一个烛台图表的例子:


4.1.15烛台图表

 


列状图 
ColumnChart控件将数据表示为一系列的垂直列,他的高度由数据值为决定。我们可以使用ColumnChart控件来创建各种类型的列状图,包含简单列,簇列等。
一个简单的图表显示一个单一的数据系列,在这里系列是一组相关的数据点。例如,一个数据系列也许是每个月的销售收益,或者是每天的旅馆出租率。图4.1.16显示了一个相应于过去四个季度的销售增长比例的数据系列:


4.1.16柱状图

HighLowOpenClose图表 
HLOCChart控件将财经数据表示为一系列的代表高,低,开放与关闭的数据系列值。垂直线的最高点与最低点代表数据点的最高值与最低值,而左边的符号标记代表值的开始点,右边的符号标记代表值的结束点。
HLOCChart控件并不需要代表开始值的数据点。相关的图表CandlestickChart将简单的数据表示为烛台。我们使用HLOCSeries配合HLOCChart控件来为HighLowOpenClose图表定义数据。图4.1.17显示了一个HighLowOpenClose图表:


4.1.17 HighLowOpenClose图表

 

线图 
LineChart控件将数据表示为了笛卡尔坐标系列中的一系列点,彼此之间由连续的线进行连接。 我们可以使用图标或是符号来表示线上的每一个数据点,或者不使用图标显示简单的线。
4.1.18是一个简单的线图的例子:


4.1.18线图

 

饼图 
我们可以使用PieChart来定义一个标准的饼图。数据提供者的数据决定饼图中相对于其他边的每一个边的尺寸。
4.1.19是一个简单的饼图的例子:


4.1.19饼图

Flex可以让我们创建圆环图。圆环图与饼图相同,所不同只是前者有一个空心与类似轮子的形状,而不是填充的圆。

块图
我们使用PlotChart控件来在笛卡尔坐标系中表示数据,其中每一个数据点有一个决定其位置的X坐标与Y坐标。我们可以定义Flex所显示的每一个数据点的形状。
4.1.20是一个简单的块图的例子:


4.1.20块图


 

 

2.6.2 使用饼图展现数据

使用饼图展现数据,代码见示例4.9

示例4.9

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>


<fx:Script>

<![CDATA[

import mx.charts.HitData;

import mx.controls.Alert;

//定义用于显示在饼图系列中的文本函数

private function pieChartLabelFunction(item:Object, field:String, index:Number, percentValue:Number):String {


return item.yearId+'';

}

//定义饼形图在鼠标经过的时候的数据提示函数

private function pieChartDataTipFunction(hitdata:HitData):String {

//获取需要绘制的图表项

var item:Object=hitdata.item;

//返回鼠标经过的时候的提示信息

return '销售量为:'+item.salesVolumn;

}


]]>

</fx:Script>

<fx:Declarations>

<!-- 定义数据  作为饼图的数据源-->

<s:ArrayCollection id="arr">

<fx:Object yearId="2000" salesVolumn="200" salesRoom="3200"/>

<fx:Object yearId="2001" salesVolumn="300" salesRoom="2000"/>

<fx:Object yearId="2002" salesVolumn="400" salesRoom="1000"/>

<fx:Object yearId="2003" salesVolumn="1000" salesRoom="3200"/>

<fx:Object yearId="2004" salesVolumn="500" salesRoom="3300"/>

<fx:Object yearId="2005" salesVolumn="600" salesRoom="1300"/>




</s:ArrayCollection>

</fx:Declarations>

<s:Panel x="137" y="60" width="490" height="344">

<!-- 定义饼形图-->

<mx:PieChart x="61" y="47" id="piechart1" height="225"

 showDataTips="true"

 dataTipFunction="pieChartDataTipFunction"

 dataProvider="{arr}"

 >

<!--定义系列-->

<mx:series>

<mx:PieSeries  field="salesVolumn" labelPosition="outside"

   labelFunction="pieChartLabelFunction"

   

   />

</mx:series>

</mx:PieChart>


</s:Panel>






</s:Application>

示例4.9中的重要属性说明如下:

Ø dataPrivider属性: 指定饼图的数据源。

Ø showDataTips属性:设置为true,表名鼠标经过的时候显示数据提示。

Ø dataTipFunction属性指定鼠标经过饼形图的系列时,以个性化的方式显示数据提示信息的回调函数。该函数返回值类型为String,作为提示信息。

private function pieChartDataTipFunction(hitdata:HitData):String {

//获取需要绘制的图表项

var item:Object=hitdata.item;

//返回鼠标经过的时候的提示信息

return '销售量为:'+item.salesVolumn;

}

回调函数中的hitData参数用于描述鼠标指向的饼形图系列,hitData参数的item属性用于封装系列所对应的数据源中的一条记录,上述代码表明当鼠标指向饼形图某个系列的时候,将会以“销售量为:xxx”的形式显示提示消息,其中,salesVolume为数据源中对应的字段名。

Ø Field属性:值为数据源中的某个字段,该字段将作为系列要呈现的数据字段。

Ø labelFunction属性:用于指定显示在饼形图系列上的个性化文本的回调函数,该函数返回值类型为String ,作为个性化文本显示。

private function pieChartLabelFunction(item:Object, field:String, index:Number, percentValue:Number):String {


return item.yearId+'';

}

回调函数中的data参数用于封装系列所对应的数据源中的一条记录,上述代码表明饼形图的文本将以"xxxx"的形式显示。

Ø labelPosition属性: 指定如何呈现数据,默认为none,表示不呈现数据,设置为其他值的时候将呈现数据.

运行示例4.9 效果如图4.1.21所示。

 

4.1.21 饼图示例

2.6.3 使用折线图展现数据

使用折线图展现3.9中的数据,代码见示例4.10.

示例4.10

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Script>

<![CDATA[

import mx.charts.HitData;

private function labelfunction(categoryValue:Object,reviousCategoryValue:Object,axis:CategoryAxis,categoryItem:Object):String{

return categoryValue+"";

}


private function tipfunction(hitdata:HitData):String{

var y :String= LineSeries(hitdata.element).yField;

if(y=='salesVolumn'){

return '销售量为: '+hitdata.item.salesVolumn;

}

return '销售量额为: '+hitdata.item.salesRoom;

}

]]>

</fx:Script>

<fx:Declarations>

<s:ArrayCollection id="arr">

<fx:Object yearId="2000" salesVolumn="200" salesRoom="3200"/>

<fx:Object yearId="2001" salesVolumn="300" salesRoom="2000"/>

<fx:Object yearId="2002" salesVolumn="400" salesRoom="1000"/>

<fx:Object yearId="2003" salesVolumn="1000" salesRoom="3200"/>

<fx:Object yearId="2004" salesVolumn="500" salesRoom="3300"/>

<fx:Object yearId="2005" salesVolumn="600" salesRoom="1300"/>




</s:ArrayCollection>

</fx:Declarations>

<s:Panel x="157" y="51" width="610" height="409">

<mx:LineChart x="9" y="65" id="linechart1"

  showDataTips="true"

  dataTipFunction="tipfunction"

  height="293" dataProvider="{arr}" width="577">

<mx:horizontalAxis>

<mx:CategoryAxis categoryField="yearId" labelFunction="labelfunction">


</mx:CategoryAxis>

</mx:horizontalAxis>

<mx:series>

<mx:LineSeries displayName="销售额" yField="salesRoom"/>

<mx:LineSeries displayName="销售量" yField="salesVolumn"/>

</mx:series>

</mx:LineChart>

<mx:Legend dataProvider="{linechart1}" direction="horizontal"/>

</s:Panel>

</s:Application>

示例4.10中的折线图定义了两个系列,即运行后会有两条折现呈现数据,分别用于显示销售量和销售额 ,示例中的重要属性说明如下:

Ø xField属性:数据源中的某个字段,该字段将作为折线图系列X轴呈现的数据字段。

Ø yField属性:数据源中的某个字段,该字段将作为折线图系列Y轴呈现的数据字段。

Ø dataTipFunction属性:指定当鼠标经过折线图系列的时候,以个性化的方式显示数据提示的回调函数。

private function tipfunction(hitdata:HitData):String{

var y :String= LineSeries(hitdata.element).yField;

if(y=='salesVolumn'){

return '销售量为: '+hitdata.item.salesVolumn;

}

return '销售量额为: '+hitdata.item.salesRoom;

}

回调函数中的hitData.element将返回鼠标指向的系列,yField属性返回折线图系列Y轴所设置的数据源字段,上述代码表明,当鼠标指向折线图系列yField属性值为salesVolumn的时候将以“销售量为:xxx”的形式提示信息,当yField属性值为salesRoom的时候将以“销售额为:xxx”的形式提示信息,其中salesVolumn salesRoom为数据源中对应的字段名。

Ø <mx:horizontalAxis>标签: 用于为折线图X轴定义呈现数据的格式,其中<mx:CategoryAxis>标签用于将数据源中的指定字段值映射到X轴上进行显示。

<mx:horizontalAxis>

<mx:CategoryAxis categoryField="yearId" labelFunction="labelfunction">


</mx:CategoryAxis>

</mx:horizontalAxis>

上述代码表明,折线图的X轴将通过回调函数labelfunction以个性化的方式来显示数据源中的yearId字段的值,其中labelfunction 定义如下:

private function labelfunction(categoryValue:Object,reviousCategoryValue:Object,axis:CategoryAxis,categoryItem:Object):String{

return categoryValue+"";

}

上述回调函数的categoryItem参数对应于数据源中的一条记录,而categoryValue则对应这条记录中的yearId字段。

Ø displayName属性:用来配合<mx:legend>标签为折线图添加图例。

运行示例4.10 效果如图3.1.22所示。

 

3.1.22 折线图

 

2.6.4 使用柱形图展现数据

使用柱形图展现3.9中的数据,代码见示例4.11

示例4.11

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<fx:Script>

<![CDATA[

import mx.charts.HitData;

import mx.controls.Alert;

protected function tipfunction(hitdata:HitData):String{

var yf:String = ColumnSeries(hitdata.element).yField;


if(yf=='salev'){

return '销售量为: '+hitdata.item.salev;

}

return '销售额为: '+hitdata.item.saler;

}

protected function linelabelfunction(categoryValue:Object,reviousCategoryValue:Object,axis:CategoryAxis,categoryItem:Object):String{



return categoryItem.year+"";


}

]]>

</fx:Script>


<fx:Declarations>

<s:ArrayCollection id="arr">

<fx:Object year="2001" salev="200" saler="3000"/>

<fx:Object year="2002" salev="800" saler="3000"/>

<fx:Object year="2003" salev="700" saler="3000"/>

<fx:Object year="2004" salev="200" saler="3000"/>

<fx:Object year="2005" salev="600" saler="3000"/>

<fx:Object year="2006" salev="200" saler="3000"/>

</s:ArrayCollection>

</fx:Declarations>

<s:Panel x="56" y="42" width="432" height="338">

<mx:ColumnChart x="61" y="61" id="piechart1" height="211"

showDataTips="true"

dataTipFunction="tipfunction"

dataProvider="{arr}"

width="334">

<mx:horizontalAxis>

<mx:CategoryAxis categoryField="year" labelFunction="linelabelfunction">


</mx:CategoryAxis>

</mx:horizontalAxis>

<mx:series>

<mx:ColumnSeries  displayName="销售量" yField="salev" />

<mx:ColumnSeries  displayName="销售额" yField="saler" />

</mx:series>

</mx:ColumnChart>

<mx:Legend dataProvider="{piechart1}" x="4" y="0" direction="horizontal"   />

</s:Panel>

</s:Application>

示例4.11中定义了两个系列,即程序运行后每条记录将会对应两个柱形,分别用于显示销售量和销售额,示例4.11中使用的标签说明如下:

Ø <mx:ColumnChart>: 根标签,用于定义图表类型为柱形图。

Ø <mx:ColumnSeries>: 为柱形图定义系列.

Ø <mx:horizontalAxis>: 为柱形图X轴定义呈现数据的格式。

运行示例4.11 效果如图3.1.23所示。

 

3.1.23 柱形图

 

 

 


任务实训部分 


 

实训任务1:视图状态的应用

训练技能点

视图状态

需求说明

使用状态切换实现用户登录。

实现思路

(1)定义状态 login main 为两种状态创建相应的界面。

(2)通过单击登录按钮改变当前状态的值,实现界面切换。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"

   creationComplete="application1_creationCompleteHandler(event)"

   >


<s:states>

<s:State name="login"/>

<s:State name="main"/>

</s:states>

<fx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.events.FlexEvent;

//生成随机码

private function generateCheckCode():String{

//初始化

var ran :Number;

var number:Number;

var code:String;

var checkCode:String="";

//生成四位随机数

for(var i:int=0;i<4;i++){

//Math.random生成数类似于0.1234

ran = Math.random();

//四舍五入

number = Math.round(ran*10000);

//如果是2的倍数则生成一个数字

if(number %2 ==0){

// 由码值生成字符串 0ascii码为48

code = String.fromCharCode(48+(number%10));

}

else{

//Aascii码为65

code = String.fromCharCode(65+(number%26));


}

checkCode+=code;

}

return checkCode;

}

 

protected function application1_creationCompleteHandler(event:Event):void

{

this.codelab.text = generateCheckCode();

}

 

 

protected function button1_clickHandler(event:MouseEvent):void

{

this.uname.text='';

this.pwd.text='';

this.code.text='';


}

 

 

protected function button2_clickHandler(event:MouseEvent):void

{

if(this.uname.text=='lee'&&this.pwd.text=='123'&&this.code.text==this.codelab.text){

this.currentState="main";

}

else{

Alert.show('用户名或者密码错误');

this.codelab.text = generateCheckCode();

}

}

 

]]>

</fx:Script>

<s:Panel includeIn="login" width="347" height="263" title="用户登录" horizontalCenter="0" verticalCenter="0">

<s:Label includeIn="login" x="75" y="31" text="用户名:" height="22" verticalAlign="middle"/>

<s:Label includeIn="login" x="75" y="61" text="密码:" height="23" verticalAlign="middle"/>

<s:TextInput includeIn="login" x="129" y="31" id="uname"/>

<s:TextInput includeIn="login" x="129" y="61" displayAsPassword="true" id="pwd"/>

<s:Button includeIn="login" x="85" y="144" label="登录" click="button2_clickHandler(event)"/>

<s:Button includeIn="login" x="213" y="144" label="重置" click="button1_clickHandler(event)"/>

<s:Label includeIn="login" x="75" y="92" text="校验码:" height="23" verticalAlign="middle"/>

<s:TextInput includeIn="login" x="131" y="93" width="48" id="code"/>

<s:Label includeIn="login" x="187" y="91" height="24" width="32" verticalAlign="middle" id="codelab"/>

<mx:LinkButton includeIn="login" x="227" y="94" label="看不清?" click="application1_creationCompleteHandler(event)"/>

</s:Panel>

<s:Label includeIn="main" text="欢迎进入主页面" horizontalCenter="0" verticalCenter="-22" height="56" width="278" verticalAlign="top" textAlign="center" fontSize="25"/>


</s:Application>

3)运行此应用 效果如图 4.2.1所示。

 

  4.2.1 状态切换

实训任务2:创建简单的程序主界面

训练技能点

控件的综合运用。

需求说明

结合Tree控件 实现导航Flex应用主界面左侧是右侧为操作区。当用户在树形导航条中选择一项功能,对应的界面会出现在右侧的操作区。

实现思路

(1)将应用程序各子功能以组件的形式创建。 “门诊挂号功能对应的Flex组件代码如下:

<?xml version="1.0" encoding="utf-8"?>

<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"

 xmlns:s="library://ns.adobe.com/flex/spark"

 xmlns:mx="library://ns.adobe.com/flex/mx" width="518" height="264" title="医院管理系统-门诊挂号">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Declarations>

<s:ArrayCollection id="ksarr">

<fx:String>内科 </fx:String>

<fx:String>外科</fx:String>

<fx:String>骨科</fx:String>

</s:ArrayCollection>

</fx:Declarations>

<s:Rect left="0" right="0" bottom="0" height="30">

<s:fill>

<s:SolidColor color="#E2EDF7"/>

      </s:fill>

</s:Rect>

<s:Button x="349" y="206" label="开单 "/>

<s:Button x="443" y="206" label="退出"/>

<s:Label x="43" y="32" text="流水账号: " width="81"/>

<s:TextInput x="160" y="32"/>

<s:Label x="43" y="72" text="科 室: " width="109"/>

<s:Label x="43" y ="115" text ="挂号日期: " width="109"/>

<s:TextInput x="160" y="110"/>

<s:DropDownList x="161" y="70" width="125"

dataProvider=" { ksarr } " prompt="==选择 ==" />

<s:Label x="43" y="153" text="患者姓名: " width="109"/>

<s:TextInput x="160" y="148"/>  

</s:Panel>

 

(2)创建MXML应用程序,用于实现主界面。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="1024"

minHeight="768" initialize="applicationl_initializeHandler(event)">

<fx:Script>

<![CDATA[




import mx.controls.Alert;

import mx.events.FlexEvent;

import mx.events.ListEvent;

import mx.formatters.DateFormatter;

private var timer:Timer;//定义时钟组件.以显示时间

protected function applicationl_initializeHandler (event:FlexEvent):void

{

this.showTime( null);

this.timer=new Timer(1000);

timer.addEventListener( TimerEvent.TIMER, showTime);

timer.start();

}

//该函数用于实时显示系统当前时间

private function showTime(evt:TimerEvent):void {

var df:DateFormatter=new DateFormatter();

var now:Date=new Date();

df.formatString="YYYYMMDDJJ:NN:SS";

this.lblDateTime.text=df.format(now);

}


//处理用户在树形导航条中单击某个节点时的操作

protected function myTree_itemClickHandler (event:ListEvent):void {

//获取用户在树形导航条中选择的节点

var selNode: String=this.myTree.selectedItem.@title;

switch(selNode)

{

case "挂号" :

doRegister();

break;

}

}

private function doRegister():void{

//实例化Register组件

var reg:Register = new Register();

reg.left =(this.nc.width-reg.width)/2;

reg.top = (this.nc.height-reg.height)/2;

this.nc.removeAllElements();

this.nc.addElement(reg);

}

]]>

</fx:Script>

<fx:Declarations>

<fx:XMLList id="treeData" xmlns="">

<root title="门诊收费">


<node title="挂号"></node>

<node title="划价"></node>

<node title="急诊"></node>

</root>

</fx:XMLList>

</fx:Declarations>

<s:Panel left="60" top="30" right="60" bottom="180" title="医院管理系统">

<mx:Accordion left="0" top="1" bottom="30" width="223">

<s:NavigatorContent label="导航栏" width="100%" height="100%">

<mx:Tree id="myTree" width="100%" height="100%" labelField="@title" dataProvider="{treeData}"

 itemClick="myTree_itemClickHandler(event)"

 borderStyle="outset">


</mx:Tree>

</s:NavigatorContent>

</mx:Accordion>

<mx:Image x="6" y="-31"  height="30" width="37" source="" scaleContent="true"/>

<mx:LinkButton x="809" y="-25" label="注销"/>

<mx:LinkButton x="857" y="-25" label="退出"/>

<mx:Accordion left="223" top="0" bottom="30" right="4">

<s:NavigatorContent name="nc" id="nc" label="操作区" width="100%" height="100%">


</s:NavigatorContent>

</mx:Accordion>

<s:Rect left="0" right="0" bottom="0" height="30">

<s:fill>

<s:SolidColor color="#e2edf7"/>

</s:fill>

</s:Rect>

<s:Label id="lblUserId" x="10" y="504" text="当前用户:Admin"/>

<s:Label id="lblDateTime" x="744" y="504" text="当前用户:Admin" width="160"/>

</s:Panel>



</s:Application>

 

 

运行应用,效果如图4.2.2所示。

 

4.2.2 主界面

 

实训任务3:模态窗体的使用

训练技能点

Ø 模态窗体。

Ø 数据绑定。

需求说明

使用模态窗体与数据绑定实现查看商品详细资料功能。在显示商品列表中,单击编辑按钮,可以打开一个模态窗体,显示商品的详细资料并修改单击删除按钮即可删除列表中的数据

实现思路:

(1)创建MXML应用程序,设计主界面。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">


<fx:Script>

<![CDATA[


 

]]>

</fx:Script>


<fx:Declarations>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

<fx:XMLList id="books">

<books>

<book>

<bookname>射雕英雄传</bookname>

<type>科普</type>

<price>100</price>

<author>金庸</author>

</book>



<book>

<bookname>射雕英雄传2</bookname>

<type>科普</type>

<price>100</price>

<author>金庸</author>

</book>


</books>

</fx:XMLList>


</fx:Declarations>

<s:Panel width="608" height="358" backgroundColor="#0F9AF2" horizontalCenter="0" verticalCenter="0">

<mx:AdvancedDataGrid x="119" y="10" id="adg1" designViewDataType="flat" width="378" dataProvider="{books.book}">

<mx:columns>

<mx:AdvancedDataGridColumn headerText="书名" dataField="bookname"/>

<mx:AdvancedDataGridColumn headerText="类别" dataField="type"/>

<mx:AdvancedDataGridColumn headerText="价格" dataField="price"/>

<mx:AdvancedDataGridColumn headerText="作者" dataField="author"/>

</mx:columns>

</mx:AdvancedDataGrid>

<s:Button x="180" y="219" label="编辑" />

<s:Button x="338" y="219" label="删除" />

</s:Panel>

</s:Application>

(2)创建编辑窗口

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" height="198" width="299">

<s:layout>

<s:BasicLayout/>

</s:layout>


<fx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.managers.PopUpManager;


var parente :test33;


protected function button1_clickHandler(event:MouseEvent):void

{


var child:XMLList = parente.books.children();

for(var v in child){


if(child[v].bookname==parente.adg1.selectedItem.bookname){

child[v].price=this.price.text;

child[v].type=this.type.text;

}

}

PopUpManager.removePopUp(this);

}


]]>

</fx:Script>

<fx:Declarations>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

</fx:Declarations>

<s:Panel x="0" y="0" width="299" height="198"   >

<s:Label x="57" y="21" text="价格" />

<s:Label x="57" y="57" text="类别"/>

<s:TextInput x="109" y="11" id="price"  text="{parente.adg1.selectedItem.price}"/>

<s:TextInput x="109" y="47" id="type"  text="{parente.adg1.selectedItem.type}"/>

<s:Button x="136" y="97" label="修改" click="button1_clickHandler(event)"/>

</s:Panel>

</s:Application>

(3)在主窗口中添加事件处理 完成功能。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">


<fx:Script>

<![CDATA[

import mx.managers.PopUpManager;

protected function button1_clickHandler(event:MouseEvent):void

{

if(this.adg1.selectedIndex>=0){

var su:SubFrame=new SubFrame();

su.parente=this;

PopUpManager.addPopUp(su,this,true);

//这个this是指将来对话框出现在哪个元素上。

PopUpManager.centerPopUp(su);


}

}

 

protected function button2_clickHandler(event:MouseEvent):void

{

if(this.adg1.selectedIndex>=0){


delete this.books.book[adg1.selectedIndex];


}

}

 

]]>

</fx:Script>


<fx:Declarations>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

<fx:XMLList id="books">

<books>

<book>

<bookname>射雕英雄传</bookname>

<type>科普</type>

<price>100</price>

<author>金庸</author>

</book>



<book>

<bookname>射雕英雄传2</bookname>

<type>科普</type>

<price>100</price>

<author>金庸</author>

</book>


</books>

</fx:XMLList>


</fx:Declarations>

<s:Panel width="608" height="358" backgroundColor="#0F9AF2" horizontalCenter="0" verticalCenter="0">

<mx:AdvancedDataGrid x="119" y="10" id="adg1" designViewDataType="flat" width="378" dataProvider="{books.book}">

<mx:columns>

<mx:AdvancedDataGridColumn headerText="书名" dataField="bookname"/>

<mx:AdvancedDataGridColumn headerText="类别" dataField="type"/>

<mx:AdvancedDataGridColumn headerText="价格" dataField="price"/>

<mx:AdvancedDataGridColumn headerText="作者" dataField="author"/>

</mx:columns>

</mx:AdvancedDataGrid>

<s:Button x="180" y="219" label="编辑" click="button1_clickHandler(event)"/>

<s:Button x="338" y="219" label="删除" click="button2_clickHandler(event)"/>

</s:Panel>

</s:Application>

 

 

(4)运行应用程序,效果如图4.2.3  4.2.4所示。

 

4.2.3 主界面

 

4.2.4 模态窗口

 

 

实训任务4Flex图表

训练技能点

Ø Flex图表。

Ø 视图状态

需求说明

结合视图状态 实现多种图表类型切换。

实现步骤:

(1)创建三种状态 并分别在三种状态下构建图表界面。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Script>

<![CDATA[

import mx.charts.HitData;

import mx.charts.chartClasses.Series;

import mx.collections.ArrayCollection;

import mx.controls.Alert;

import mx.rpc.events.FaultEvent;

import mx.rpc.events.ResultEvent;


protected function xFunction(categoryValue:Object, previousCategoryValue:Object, axis:CategoryAxis, categoryItem:Object):String {


return  categoryItem.yearId+"";

}

protected function pieTipFunction(hitdata:HitData):String {

var item:Object = hitdata.item;

return "销售量为:"+item.salesVolumn;

}

protected function tipFunction(hitdata:HitData):String {

var y :String ;


if(hitdata.element is LineSeries){

y = LineSeries(hitdata.element).yField;

}

else{

y = ColumnSeries(hitdata.element).yField;

}


if(y=='salesRoom'){

return "销售额为: "+hitdata.item.salesRoom;

}

return  "销售量为: "+hitdata.item.salesVolumn;

}






]]>

</fx:Script>

<fx:Declarations>

<s:ArrayCollection id="arr">

<fx:Object yearId="2000" salesVolumn="200" salesRoom="3200"/>

<fx:Object yearId="2001" salesVolumn="300" salesRoom="2000"/>

<fx:Object yearId="2002" salesVolumn="400" salesRoom="1000"/>

<fx:Object yearId="2003" salesVolumn="1000" salesRoom="3200"/>

<fx:Object yearId="2004" salesVolumn="500" salesRoom="3300"/>

<fx:Object yearId="2005" salesVolumn="600" salesRoom="1300"/>




</s:ArrayCollection>




</fx:Declarations>

<s:states>

<s:State name="pie"/>

<s:State name="line"/>

<s:State name="column"/>

</s:states>

<s:Panel x="83" y="50" width="673" height="414" title="login">

<mx:ColumnChart  x="24" y="61" showDataTips="true" dataTipFunction="tipFunction"  id="columnchart1" width="367" height="258"  visible.pie="false" visible.line="false">

<mx:horizontalAxis>

<mx:CategoryAxis categoryField="yearId" labelFunction="xFunction">


</mx:CategoryAxis>

</mx:horizontalAxis>

<mx:series>

<mx:ColumnSeries displayName="销售额" yField="salesRoom" />

<mx:ColumnSeries displayName="销售量" yField="salesVolumn" />

</mx:series>

</mx:ColumnChart>


<mx:PieChart    x="68" y="73" id="piechart1" width="312" height="236"  visible.line="false" visible.column="false"

showDataTips="true" dataTipFunction="pieTipFunction"  >

<mx:series>

<mx:PieSeries   field="salesRoom" labelPosition="callout" />

</mx:series>

</mx:PieChart>


<mx:LineChart   dataTipFunction="tipFunction"  showDataTips="true" x="43" y="69" id="linechart1" width="364" height="252"  visible.pie="false" visible.column="false">

<mx:horizontalAxis>

<mx:CategoryAxis categoryField="yearId" labelFunction="xFunction">


</mx:CategoryAxis>

</mx:horizontalAxis>

<mx:series>

<mx:LineSeries displayName="销售额" yField="salesRoom" />

<mx:LineSeries displayName="销售量" yField="salesVolumn" />

</mx:series>

</mx:LineChart>

<mx:Legend   id="leg"/>

<s:RadioButton x="274" y="15" label="饼图" />

<s:RadioButton x="336" y="15" label="柱图" />

<s:RadioButton x="393" y="15" label="折线图" />





</s:Panel>

</s:Application>

(2)为单选按钮添加状态切换代码 并添加动画效果。

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

   xmlns:s="library://ns.adobe.com/flex/spark"

   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

<s:layout>

<s:BasicLayout/>

</s:layout>

<fx:Script>

<![CDATA[

import mx.charts.HitData;

import mx.charts.chartClasses.Series;

import mx.collections.ArrayCollection;

import mx.controls.Alert;

import mx.rpc.events.FaultEvent;

import mx.rpc.events.ResultEvent;


protected function xFunction(categoryValue:Object, previousCategoryValue:Object, axis:CategoryAxis, categoryItem:Object):String {


return  categoryItem.yearId+"";

}

protected function pieTipFunction(hitdata:HitData):String {

var item:Object = hitdata.item;

return "销售量为:"+item.salesVolumn;

}

protected function tipFunction(hitdata:HitData):String {

var y :String ;


if(hitdata.element is LineSeries){

y = LineSeries(hitdata.element).yField;

}

else{

y = ColumnSeries(hitdata.element).yField;

}


if(y=='salesRoom'){

return "销售额为: "+hitdata.item.salesRoom;

}

return  "销售量为: "+hitdata.item.salesVolumn;

}



protected function radiobutton1_clickHandler(event:MouseEvent):void

{



currentState='pie';

this.piechart1.dataProvider=arr;

this.leg.dataProvider=null;

this.columnchart1.dataProvider=null;

this.linechart1.dataProvider=null;

this.leg.dataProvider=null;

}



protected function radiobutton2_clickHandler(event:MouseEvent):void

{



columnchart1.dataProvider=arr;

this.leg.dataProvider=this.columnchart1;

currentState='column';

this.piechart1.dataProvider=null;

this.linechart1.dataProvider=null;

this.leg.dataProvider=this.columnchart1;

}



protected function radiobutton3_clickHandler(event:MouseEvent):void

{



linechart1.dataProvider=arr;

this.leg.dataProvider=this.linechart1;

currentState='line';

this.columnchart1.dataProvider=null;

this.piechart1.dataProvider=null;

this.leg.dataProvider=this.linechart1;

}


]]>

</fx:Script>

<fx:Declarations>

<s:ArrayCollection id="arr">

<fx:Object yearId="2000" salesVolumn="200" salesRoom="3200"/>

<fx:Object yearId="2001" salesVolumn="300" salesRoom="2000"/>

<fx:Object yearId="2002" salesVolumn="400" salesRoom="1000"/>

<fx:Object yearId="2003" salesVolumn="1000" salesRoom="3200"/>

<fx:Object yearId="2004" salesVolumn="500" salesRoom="3300"/>

<fx:Object yearId="2005" salesVolumn="600" salesRoom="1300"/>




</s:ArrayCollection>



<mx:SeriesInterpolate id="si" duration="2000">


</mx:SeriesInterpolate>

</fx:Declarations>

<s:states>

<s:State name="pie"/>

<s:State name="line"/>

<s:State name="column"/>

</s:states>

<s:Panel x="83" y="50" width="673" height="414" title="login">

<mx:ColumnChart  x="24" y="61" showDataTips="true" dataTipFunction="tipFunction"  id="columnchart1" width="367" height="258"  visible.pie="false" visible.line="false">

<mx:horizontalAxis>

<mx:CategoryAxis categoryField="yearId" labelFunction="xFunction">


</mx:CategoryAxis>

</mx:horizontalAxis>

<mx:series>

<mx:ColumnSeries displayName="销售额" yField="salesRoom" showDataEffect="{si}"/>

<mx:ColumnSeries displayName="销售量" yField="salesVolumn" showDataEffect="{si}"/>

</mx:series>

</mx:ColumnChart>


<mx:PieChart    x="68" y="73" id="piechart1" width="312" height="236"  visible.line="false" visible.column="false"

showDataTips="true" dataTipFunction="pieTipFunction"  >

<mx:series>

<mx:PieSeries showDataEffect="{si}"  field="salesRoom" labelPosition="callout" />

</mx:series>

</mx:PieChart>


<mx:LineChart   dataTipFunction="tipFunction"  showDataTips="true" x="43" y="69" id="linechart1" width="364" height="252"  visible.pie="false" visible.column="false">

<mx:horizontalAxis>

<mx:CategoryAxis categoryField="yearId" labelFunction="xFunction">


</mx:CategoryAxis>

</mx:horizontalAxis>

<mx:series>

<mx:LineSeries displayName="销售额" yField="salesRoom" showDataEffect="{si}"/>

<mx:LineSeries displayName="销售量" yField="salesVolumn" showDataEffect="{si}"/>

</mx:series>

</mx:LineChart>

<mx:Legend   id="leg"/>

<s:RadioButton x="274" y="15" label="饼图" click="radiobutton1_clickHandler(event)"/>

<s:RadioButton x="336" y="15" label="柱图" click="radiobutton2_clickHandler(event)"/>

<s:RadioButton x="393" y="15" label="折线图" click="radiobutton3_clickHandler(event)"/>





</s:Panel>

</s:Application>

3)运行应用程序,效果如图4.2.5所示。

 

4.2.5 Flex图表

 

 

 

 

 

巩固练习


选择题

1.  关于Flex中视图状态,说法正确的是()

A.  应用程序默认的视图状态为default状态。

B.  应用程序默认的视图状态为<s:states>中定义的第一个状态。

C.  includeIn表示向视图中添加组件。

D.  excludeFrom表示向视图中添加组件。

2.  能够正确从目标对象的dragDrop事件中获取拖放数据的是()

A.  Var dgRow:Object=event.dragSource.dataFormat('item')[0]

B.  Var dgRow:Object=event.dragSource.dataFormat('items')[0]

C.  Var dgRow:Object=event.dragSource.dataFormat('items')

D.  Var dgRow:Object=event.dragSource.dataFormat('item')

3.  关于Flex图表组件的说法,正确的是()

A.  图表需要包含一种图表类型,若干系列 和坐标轴。

B.  饼形图对应的系列标签是<mx:pieSeries>

C.  为了使鼠标经过图表时显示提示信息,需要将showDataTip属性设置为true

D.  dataTipFunction属性用于指定当鼠标经过图表中的系列时显示提示信息的回调函数,函数返回值类型为object

简答题

(1)什么是视图状态。

(2)怎样在不可直接拖拽的组件上实现拖拽操作?

操作题

开发Flex应用程序,将AdvancedDataGrid中的数据拖拽到list组件中。