Application>,说白了就是通过这个文件来定义Flash的swf格式文件,
只不过编译后就直接将生成的swf封装到了满足"一定格式"的HTML文件中了。
**注意:
我们知道Flash文件中只能有ActionScript代码,没听说过也可以有MXML文件,
所以Flex中的这个MXML文件只是为了方便视图界面的开发和格式的美观优雅而特别订制的,
其实运行Flex的应用时,首先会将MXML文件中的定义内容转换成相对应的ActionScript代码(变量、对象等),
然后在运行所有ActionScript代码,也就是说如果有MXML的内容的话就先把它们转换成ActionScript,
然后将原来的ActionScript和刚转换成的ActionScript一起进行编译(编译后的文件默认会输出到bin-debug目录),使之作用于Flash文件之上。
**注意:
在MXML文件中只能在Script>...
Script>标签内部使用
[CDATA[ActionScript代码]]>段的形式书写ActionScript代码,
不能像在as文件中那样写ActionScript代码。
*ActionScript3的作用:
就如上说,就是用来定义Flash文件(swf)中的对象、事件等组件的语言。
**技巧:
由上边说明知道ActionScript代码会在MXML文件内容转换完后才一起执行,
这样一来就可以在ActionScript代码中直接引用MXML文件中通过元素定义(MXML会将元素的ID值最为定义的对象名称)的对象了,
无需担心会访问不到,因为现将MXML转换成ActionScript,然后在统一编译执行ActionScript代码,最后生成封装有swf文件的HTML等一些文件。
**注意:
一般Flex应用中会将MXML和ActionScript这两种方式结合使用,以达到最佳效果。
6.FlexBuilder3提供了3种类型的项目:
Flex项目、Flex库项目和ActionScript项目。
*Flex项目:
就是我们要使用的。
我们可以在项目中导入我们自己定义的Flex类库SWC文件(类似与Java中的jar包)。
它有一个html-template目录,存放的是模板文件,输出到bin-debug目录中的文件就是以html-template目录中模板文件为模板生成的。
所以修改html-template模板中的某个设置将会影响输出的内容,有的时候为了实现某个界面效果可以修改模板文件。
**注意:
SWC库(库中可以封装图片、声音等素材文件、程序(组件或自定义组件)等)文件类型分为普通类型和RSL类型,
虽然都是库包,但是前者使用时一般要封装到swf文件中使用,就是不需另外导入对应的SWC库包;而后者就是使用RSL机制,
让swf文件在使用SWC库中的内容时才运行(加载SWC库包),所以需要导入SWC库包到项目,这种属于动态机制。
*Flex库项目:
就是将要封装的内容放到src中,然后编译项目,就会在bin目录中生成对一个的SWC库文件。
*ActionScript项目:
就是编写ActionScript语言对应的.as文件,然后编译生成对应的SWC库包,供Flex项目导入使用。
7.使用MXML来实现事件处理机制:
用一个例子来演示。
<1>首先创建一个MXMLComponent文件,使用已有的ActionScript组件来组装一个自定义的组件。
其实就是创建一个新类,继承已经存在的组件(如Panel),然后在自定义类中封装几个已存在的组件作为属性,以组成自己的类!
!
xmlversion="1.0"encoding="utf-8"?
>
Panelxmlns:
mx="layout="absolute"title="后台管理">
Labelx="41"y="30"text="用户名:
"/>
Labelx="41"y="76"text="密 码:
"/>
TextInputid="t_username"x="119"y="28"borderColor="#0B65A4"backgroundColor="#CE6363"backgroundAlpha="0.18"/>
--displayAsPassword="true"表示输入密码后用黑点儿显示-->
TextInputid="t_password"x="119"y="76"displayAsPassword="true"borderColor="#0B65A4"backgroundColor="#CE6363"backgroundAlpha="0.18"/>
--为按钮注册鼠标点击监听器事件方法clickButton-->
Buttonx="119"y="123"label="登陆"width="72"click="clickButton()"/>
--这里不是为该自定义组件注册一个Event事件,而是指定该组件可以注册这个事件,事件类型叫做"login"-->
Metadata>
[Event(name="login",type="flash.events.Event")]
Metadata>
--点击按钮触发事件方法后,为整个自定义组件的事件流中添加一个新的上边声明了的login类型的事件
此事件添加到事件流后,如果自定义组件或子节点组件有注册login类型的监听器,那么会立即触发-->
Script>
[CDATA[
internalfunctionclickButton():
void{
//向这个组件的事件流中制造一个新的事件,以便可以触发对应的监听器
this.dispatchEvent(newEvent("login"));
}
]]>
Script>
Panel>
*说明:
因为表单有登陆按钮对象,所以要为按钮注册一个"登陆事件‘(即鼠标点击事件),
当点击时当然就会触发事件监听方法,进而完成对应的功能(判断用户名、密码等)。
*注意:
这样一个自定义组件不能独立运行,只能供一个MXML文件引用而使用。
所以是否触发login类型的事件要看引用该组件对象的MXML文件中的声明了。
见下边!
!
<2>在MXML文件中引入自定义组件,使用LoginForm>元素引用(也可以从组件视图上拖动)。
xmlversion="1.0"encoding="utf-8"?
>
Applicationxmlns:
mx="layout="vertical"xmlns:
ns1="*">
--事件监听方法,当自定义组件有login类型的事件发生时,就会调用loginClick()方法-->
Script>
[CDATA[
importmx.controls.Alert;
//监听器方法
internalfunctionloginClick(evt:
Event):
void{
Alert.show("登陆成功","提示");
}
]]>
Script>
--在MXML中引入自定义组件,并且为组件注册login类型的事件监听器,监听方法为loginClick,参数一定要传入event对象,
之所以要传入参数是因为声明的事件监听方法要接收这个参数-->
LoginFormid="loginForm"login="loginClick(event)"verticalAlign="middle">
LoginForm>
*说明:
login="loginClick(event)"中的login是事件类型,而loginClick则是事件监听器方法
Application>
<3>总结:
上边例子中,首先在自定义组件中为自定义组件声明了一个可以使用的事件类型"login",
然后为自定义组件中的按钮的鼠标点击事件注册监听器方法为clickButton()方法,方法体中是为自定义组件的事件流中制造一个login类型的事件。
也就是说运行时,点击按钮后,会触发clickButton方法,然后该方法为自定义组件事件流中制造一个新的login事件,
这回导致注册了login事件类型的监听器被调用,即loginClick被调用。
这是上边例子点击登陆后的操作流程。
<4>上边为自定义组件声明的事件类型都是ActionScript提供的事件Event类型的,我们当然也可以想在ActionScript中那样,定义自定义的事件类型。
//自定义事件类型
publicclassLoginEventextendsEvent{
//保存用户名
publicvarusername:
String;
//保存密码
publicvarpassword:
String;
publicfunctionLoginEvent(type:
String){
super(type,false,false);
}
}
*修改<1>中代码:
Metadata>
--type的值改成了自定义事件类型-->
[Event(name="login",type="com.events.LoginEvent")]
Metadata>
Script>
[CDATA[
importcom.events.LoginEvent;
internalfunctionclickButton():
void{
//创建自定义事件对象,并且指定类型名为"login"
varloginEvent:
LoginEvent=newLoginEvent("login");
//得到用户名值
loginEvent.username=t_username.text;
//得到密码值
loginEvent.password=t_password.text;
//向事件流中制造事件
this.dispatchEvent(loginEvent);
}
]]>
Script>
*修改<2>中代码:
//此处参数类型改成了LoginEvent自定义类型,如果不改将会得不到username和password属性值
internalfunctionloginClick(evt:
LoginEvent):
void{
//判断用户名和密码
if((evt.username=="admin")&&(evt.password=="admin")){
Alert.show("登陆成功","提示");
return;
}
Alert.show("登陆失败","警告");
}
*说明:
其实我们可以直接在按钮的鼠标点击事件中进行表单的验证,不过如果这样代码的复用能力就比较差,
因为我们可能会在很多地方都会使用自定义组件,如果验证写在鼠标单击按钮事件方法中,那么在每一次引用自定义组件后,
如果各个需求的验证方法不同,那么就要总是修改自定义组件的鼠标点击事件方法中的代码了。
而向上边那样写,就无需修改自定义组件中的代码了。
8.数据绑定:
就是当数据源对象的数据发生变化时,目标对象的数据会自动更新,而不需要我们再编写代码去强制更新。
*绑定的内部原理:
绑定实际也是借助事件机制来完成的,当目标使用了数据绑定的时候,
目标对象就会监听数据源对象的某一固定事件。
当数据源发生变化时,数据源就会制造出那个固定的事件(ChangeEvent事件),
此时目标对象的监听机制会被触发,即通知目标对象更新数据。
不过这个过程都是由Flex完成,不用我们手动干预!
!
*绑定的前提条件:
数据源对象的数据和目标对象的数据格式相同。
<1>方法一:
针对MXML文件可以使用的方法。
在为组件对象的元素属性赋值时,使用"{}"直接将数据源直接绑定到对象组件的某个属性上,这样就可以了。
例子:
--绑定语句:
fontSize="{h_slider.value}"-->
Labelid="f_label"x="319"y="61"text="滑动条数据绑定"fontSize="{h_slider.value}"/>
HSliderid="h_slider"x="276"y="284"minimum="20"maximum="40"snapInterval="10"/>
说明:
当滑动条滑动时,将会改变滑动条的数值,因为我们将Label>的fontSize属性值和滑动条的数值进行了绑定,
所以滑动条变化后的数值将会作为Label>的fontSize属性值。
<2>方法二:
针对MXML和ActionScript结合使用的方法。
在组件对象的元素属性中,使用"{}"把某个ActionScript的方法的返回值作为数据源绑定到该组件对象属性上。
同时ActionScript的这个方法的参数要使用[Bindable]绑定符号。
例如:
Script>
[CDATA[
//作为方法的参数,如果不指定[Bindable]那么参数变化后不会通知目标进行更新数据
[Bindable]
privatevarnumber:
int;
//下边调用的方法,做平方运算
internalfunctionsquare(num:
int):
int{
returnnum*num;
}
]]>
Script>
Labelx="276"y="244"text="结果"fontSize="17"id="f_label"/>
--这里把square方法的返回值作为数据源,而number属性作为参数进行绑定,有规则知道作为参数的number属性要使用[Bindable]进行声明,
表明为该属性指定一个监听器(由Flex自己完成),当属性值变化时就表示触发该事件,然后就会通知数据绑定目标进行更新操作(也是由Flex自己完成)-->
TextInputx="323"y="249"width="113"text="{square(number)}"/>
--这里把滑动块的值作为数据源,目标对象为通过ActionScript定义的number属性;
当滑动条变动的时候会触发change属性指定的方法,不过这里不是方法,而是数据绑定,
当变化时会将滑动条的值赋值给通过ActionScript定义的number属性变量-->
HSliderx="276"y="284"id="h_slider"minimum="1"maximum="10"change="{number=h_slider.value}"/>
**补充关于[Bindable]的知识:
**声明的标准格式:
[Bindable(event="eventType")]表示为添加该声明的属性(数据源)制造事件,就是说当数据源变化时,
向事件流中制造一个事件,以便触发事件(Flex内部定义好的)去通知目标对象进行更新操作(由Flex完成)!
!
**我们上边为什么只是指定了[Bindable]呢?
----因为如果不指定默认值为[Bindable(event="propertyChange")],等价于[Bindable],
就是说当属性改变的时候制造一个事件,以便Flex通知目标对象进行更新操作。
**扩展能力补充:
[Bindable]不仅可以用在属性上,也可以用在getter或setter方法(2选1即可)上,也可以作用在类的声明上。
A.作用在getter或setter方法上:
成为方法级绑定。
实现的效果和[Bindable]作用在属性上差不多。
例子:
//1.创建一个ActionScript的类
publicclassBindClass{
//属性处则不用进行绑定了
privatevarage:
int;
//建立绑定关系
[Bindable]
publicfunctiongetAge():
int{
returnthis.age;
}
//属性的setter方法,[Bindable]作用在getter或setter方法中选其一即可
publicfunctionsetAge(age:
int):
void{
this.age=age;
}
}
//2.在MXML文件中使用BindClass类
Script>
[CDATA[
//定义一个类对象,供下边的MXML文件访问
privatevarbc:
BindClass=newBindClass();
//下边调用的方法,做平方运算
internalfunctionsquare(num:
int):
int{
returnnum*num;
}
]]>
Script>
Labelx="276"y="244"text="结果"fontSize="17"id="f_label"/>
--因为BindClass绑定的是getter和setter方法,
所以暴漏出来的是get或set关键字后边的部分(可以作为属性直接使用),
不过此时就不能直接访问BindClass类的age属性,因为并没有绑定age属性,
下边text="{square(bc.Age)}"中的bc.Age表示调用的是getAge()方法-->
TextInputx="323"y="249"width="113"text="{square(bc.Age)}"/>
--change="{bc.Age=h_slider.value}"中的bc.Age表示调用的是setAge()方法-->
HSliderx="276"y="284"id="h_slider"minimum="1"maximum="10"change="{bc.Age=h_slider.value}"/>
B.作用在类的声明上:
称为对象(类)级别绑定,[Bindable]标签用于公有类时,
这个类的所有public类型的变量和setter、getter方式定义的方法都可以用于绑定。
例如:
//1.创建一个BindClass类型,并且绑定类级别的绑定
[Bindable]
publicclassBindClass{
--下边的属性会因为定义了类级的绑定自动进行绑定-->
//定义成public主要使用与演示效果