第二篇 FLEX核心开发技术
在第一篇中我们了解了当前RIA世界的现状,后半部分也就是第二章,宏观地介绍了FLEX相关一些很重要也很基础的概念。本篇将如题所述深入详细地探讨FLEX编程的方方面面,以及作者的经验总结。本篇这也是本书的重点。
第三章 FLEX编程语言
不知道你注意到没有,在我们应用FLEX开发的过程中,构建表现层布局,MXML编程和ACTIONSCRIPT基本上都可以满足我们的需求,那么MXML和ACTIONSCRIPT分别的侧重点又是什么呢,或者换一种表达方式,MXML和ACTIONSCRIPT分别的长处和短处又是什么呢。为了分析这个问题,我们引用在企业级开发中的另一种相似的情景,尤其是对J2EE熟悉的开发者来说,就是JSP和SERVLET的角色和使命。
JSP从本质上来说是SERVLET的另一种表达方式,都是以单例的形式多线程的响应客户端请求。从编译角度来说,JSP首先会被转换成SERVLET的形式,以CLASS字节码文件等待JAVA虚拟机JVM的最终解析和执行。JSP更擅长从最终用户的角度构建系统的表现层,而传统的SERVLET则更擅长业务逻辑的处理。反观我们的MXML和ACTIONSCRIPT,其所处的角色和相对的关系与JSP和SERVLET有着及其的相似性。MXML以标签的方式来布局最终用户的表现层,MXML类实际上是ACTIONSCRIPT类的另一种表现方式,之所以会有这种表现方式,是因为它能够及其方便开发者快速的构建用户的表现层,而没有必要在ACTIONSCRIPT脚本中以硬编程的方式来实现布局,尤其是复杂的页面布局。编译期,MXML也会以ACTIONSCRIPT文件为中间形态,最后形成SWF字节码供AVM虚拟机解析和执行。
MXML可以快速的构建表现层页面是其优点之一,另外还有一点,就是MXML本身的数据绑定机制的实现。这一点可以让我们很好地封装和隔离页面代码和逻辑代码,为和服务器端的集成提供了很基础的保证。
3.1 利用容器类布局表现层
MXML标准实现包括了两种类型的组件,控件和容器。控件一般指TextInput, Label,Button等实体页面元素。相应地,容器一般指一块长方形的空间,在这个空间里可以按照当前这个容器预定义的放置规则放置控件和别的容器。在种类上容器分布局性容器和导航性容器两种。
上面我们提到容器的放置规则,那么什么是放置规则呢?我们现在讨论这个话题。举个例子,对于中国象棋和国际象棋来说,棋子的摆放和挪动规则是不一样的,我们不能在中国象棋的棋盘上玩国际象棋。MXML容器内页面元素的放置规则可从总体上分为以下几种。
一.横向或纵向规则。
二.网格式规则。
三.坐标式规则。
四.点缀式规则。
五.复用式规则。
下面我们将举例分析以上四种方式。
3.1.1 横向纵向规则
在FLEX所有的标准容器内以字母H或V打头的容器组件基本都属于这种规则,如Hbox,/Vbox,HdevidedBox/VdevidedBox, 它们在本质上是近亲,有着共同的祖先Box,参考图3-1-1-1,
在Box容器中有个direction属性,可以设其为horizontal或者vertical,在功能上和Vbox和Hbox一摸一样。实际上,Vbox和Hbox就是direction属性已经初始化为horizontal或者vertical的Box,参考下面两个例子实际上是等同的。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Box id="TEST1" direction="horizontal" label="horizontal box">
</mx:Box>
<mx:Box id="TEST2" direction="vertical" label="vertical box">
</mx:Box>
</mx:Application>
以及
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:HBox id="TEST1" label="horizontal box">
</mx:HBox>
<mx:VBox id="TEST2" label="vertical box">
</mx:VBox>
</mx:Application>
对于Hbox/Vbox的基本用法,参考示例:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel height="75%" width="75%"
paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">
<mx:HBox borderStyle="solid" paddingTop="10" paddingBottom="10"
paddingLeft="10" paddingRight="10">
<mx:Button label="Button 1"/>
<mx:Button label="Button 2"/>
<mx:Button label="Button 3"/>
<mx:ComboBox/>
</mx:HBox>
<mx:VBox borderStyle="solid" paddingTop="10" paddingBottom="10"
paddingLeft="10" paddingRight="10">
<mx:Button label="Button 1"/>
<mx:Button label="Button 2"/>
<mx:Button label="Button 3"/>
<mx:ComboBox/>
</mx:VBox>
</mx:Panel>
</mx:Application>
运行结果:
在实现上HdividedBox/VdividedBox分别是direction属性已经被预设为horizontal和vertical的DividedBox。DividedBox比其父亲Box多了一个可以通过拖动重新设定容器大小的属性。
参考实例代码
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundColor="white" width="531" height="312">
<mx:HDividedBox width="100%" height="100%">
<mx:Panel title="zone 1" width="30%" height="100%">
</mx:Panel>
<mx:VDividedBox width="70%" height="100%">
<mx:Panel title="zone 2" width="100%" height="50%">
</mx:Panel>
<mx:Panel title="zone 3" width="100%" height="50%">
</mx:Panel>
</mx:VDividedBox>
</mx:HDividedBox>
</mx:Application>
运行结果:
3.1.2网格式规则
在FLEX标准组件库中利用网格式布局孩子元素的主要有Grid和Tile两个。所谓网格式布局就是指在一个长方形的容器空间内按照预设的行数和列数对空间进行打格子划分,孩子元素可被放到相应的格子中去。Grid容器利用配套的GridRow和GridItem元素来设置网格布局。参考示例
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Grid id="grid">
<mx:GridRow id="row1" >
<mx:GridItem>
<mx:Button label="Button 1"/>
</mx:GridItem>
<mx:GridItem>
<mx:Button label="Button 2"/>
</mx:GridItem>
<mx:GridItem>
<mx:Button label="Button 3"/>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow id="row2">
<mx:GridItem colSpan="3" horizontalAlign="center">
<mx:Button label="Button 4"/>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow id="row3">
<mx:GridItem/>
<mx:GridItem colSpan="2" horizontalAlign="center">
<mx:Button label="Button 5"/>
</mx:GridItem>
</mx:GridRow>
</mx:Grid>
</mx:Application>
运行结果:
Tile则默认以最大的孩子组件的大小为标准,以相同的高度和宽度来布局它的孩子组件。也可以通过cellWidth和cellHeight属性设定孩子元素的大小。参考示例:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal">
<mx:Panel height="291" width="243"
paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">
<mx:Tile direction="vertical" borderStyle="inset"
horizontalGap="10" verticalGap="15"
paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">
<mx:Button label="1" height="50" width="75"/>
<mx:Button label="2" height="50" width="75"/>
<mx:Button label="3" height="50" width="75"/>
<mx:Button label="4" height="50" width="75"/>
<mx:Button label="5" height="50" width="75"/>
<mx:Button label="6" height="50" width="75"/>
</mx:Tile>
</mx:Panel>
<mx:Panel height="293" width="321"
paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">
<mx:Tile direction="horizontal" borderStyle="inset"
horizontalGap="10" verticalGap="15"
paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">
<mx:Button label="1" height="50" width="75"/>
<mx:Button label="2" height="50" width="75"/>
<mx:Button label="3" height="50" width="75"/>
<mx:Button label="4" height="50" width="75"/>
<mx:Button label="5" height="50" width="75"/>
<mx:Button label="6" height="50" width="75"/>
</mx:Tile>
</mx:Panel>
</mx:Application>
运行结果:
3.1.3 坐标式规则
在FLEX标准容器组件中采用显示绝对坐标布局孩子元素的容器是Canvas组件,它通过孩子元素的x和y属性来设定其在Canvas长方形空间内的位置。参考示例:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel height="255" width="311" paddingTop="5" paddingLeft="5" paddingRight="5" paddingBottom="5">
<mx:Canvas borderStyle="solid" height="200" width="261">
<mx:VBox right="115" bottom="50" width="75" height="75" backgroundColor="#0080C0"/>
<mx:VBox right="70" bottom="30" width="75" height="75" backgroundColor="#FFFF80"/>
<mx:VBox right="25" bottom="10" width="75" height="75" backgroundColor="#8080C0" alpha="0.8"/>
</mx:Canvas>
</mx:Panel>
</mx:Application>
运行结果:
3.1.4点缀式规则
一. 所谓点缀式规则,实际上是指当前容器参与同级容器的布局中,只是起点缀的作用,其大小不会影响到它点缀对象的大小的一种容器,比如ControlBar和ApplicationControlBar,都一般和Panel容器或者TitleWindow容器一起出现扮演点缀的角色。ApplicationControlBar 通常被用来格式化页面布局的顶端,如顶部主菜单栏、顶部按钮等。它也通常和Panel或者TitleWindow一起使用。参考示例:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
]]>
</mx:Script>
<mx:XMLList id="menu">
<menuitem label="File">
<menuitem label="New" data="New"/>
<menuitem label="Open" data="Open"/>
<menuitem label="Save" data="Save"/>
<menuitem label="Exit" data="Exit"/>
</menuitem>
<menuitem label="Edit">
<menuitem label="Cut" data="Cut"/>
<menuitem label="Copy" data="Copy"/>
<menuitem label="Paste" data="Paste"/>
</menuitem>
<menuitem label="View"/>
</mx:XMLList>
<mx:Array id="arr">
<mx:String>Item 1</mx:String>
<mx:String>Item 2</mx:String>
<mx:String>Item 3</mx:String>
</mx:Array>
<mx:ApplicationControlBar id="dockedBar" height="100%" dock="true">
<mx:MenuBar height="100%"
dataProvider="{menu}"
labelField="@label"
showRoot="true"/>
<mx:HBox paddingBottom="5"
paddingTop="5">
<mx:ComboBox dataProvider="{arr}"/>
<mx:Spacer width="100%"/>
<mx:TextInput id="myTI" text=""/>
<mx:Button id="srch1"
label="Search"
click="Alert.show('find')"/>
</mx:HBox>
</mx:ApplicationControlBar>
<mx:TextArea width="100%" height="100%"/>
</mx:Application>
注意到ApplicationControleBar组件的高度已经设为100%,同级组件TextArea的高度和宽度也设为100%,可是显示结果ApplicationControlBar的高度还是默认高度,并没有覆盖掉TextArea的空间。运行结果为
而相应地对于ControlBar容器,和ApplicationControlBar相似,只不过ControlBar用来格式页面底部的布局。它也通常和Panel或者TitleWindow一起使用。参考示例:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
private function doit():void {
}
]]>
</mx:Script>
<mx:Panel title="CONTROLBAR DEMO"
paddingTop="10" paddingBottom="10"
paddingLeft="10" paddingRight="10">
<mx:HBox width="250" height="200">
</mx:HBox>
<mx:ControlBar width="250">
<mx:Label text="TEST"/>
<mx:NumericStepper/>
<mx:Spacer width="100%"/>
<mx:Button label="DO"
click="doit();"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>
运行结果:
3.1.5复用式规则
所谓复用规则是指,在某些容器的长方形空间内,所有的孩子元素中在某一时刻只有一个处于显示状态,其他的都处于隐藏状态。基本所有的导航式容器都遵循这种规则。导航类容器在功能上不具有布局类容器的特性,它基本上都是以分层的方式共享同一块容器空间(孩子元素的状态分为两种显示和隐藏),并通过设定其内置的selectedChild或者selectedIndex属性的方式在不同的层之间导航。为充分利用有限空间提供了很好的方案。导航类容器主要分为:Accordion,TabNavigator,ViewStack。
一. Accordion 包含一个子容器的集合,并且通过bar点击的方式设置内置的selectedChild或者selectedIndex属性在不同子容器间导航,示例代码:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Accordion id="accord" height="234" width="526">
<mx:Form label="label1">
<mx:FormItem label="First Name">
<mx:TextInput />
</mx:FormItem>
</mx:Form>
<mx:Form label="label2">
</mx:Form>
<mx:Form label="label3">
</mx:Form>
<mx:Form label="label4">