//什么是Flex
Flex 是一个针对企业级富互联网应用的表示层解决方案。具体地说,Flex是一种应用程序框架
富互联网应用程序,Rich Internet Application,简称RIA,将桌面应用程序的强交互性和传统Web应用的灵活性结合,对比HTML,表现更花哨,更有趣,更有个性。

//Flex的特性
使用矢量图形;丰富的组件库;对多媒体的广泛支持;
与服务器端的通信:除了可以加载XML和其它文本资料外,Flex还可以和ASP、 ASP.NET、PHP、JSP等多种服务器端程序通信,连接远程WebService,同时Flex还支持Remoting和 Socket等高级数据通信方式。

//Flex和Flash
Flash 的重用性不好;Flex数据交互能力更突出

//Flex程序的组成
以 mxml为后缀的程序文件;以as为后缀的ActionScript文件;以css为后缀的样式表文件

//MXML文件结构
是一个标准的XML文件,包括了版本、编码(可选,默认为utf-8)、命名空间(xmlns)。在一个Flex项目中,可能有很多个MXML文件,但作为程序入口的运行文件只有一个,主文件的标识是根节点为mx:Application,一个程序中只能出现一个mx:Application节点。

//添加按钮事件
当为一个按钮添加click事件时,系统会自动提示生成EventHandler。注意要先定义按钮的ID。

//自定义MXML组件
新建 MXML组件,组件会出现在“组件”面板上,像使用Flex自带组件一样,将其拖放到主程序中即可。

//在MXML文件中插入 ActionScript块
通常情况下,将<mx:Script>标签放在紧跟根节点的位置,放在其他MXML代码的前面:
<mx:Application xmlns:...>
 <mx:Script>
  <![CDATA[
   // 这里是ActionScript代码
  ]]>
 </mx:Script>
</mx:Application>

//调试
F8是运行。F5单步跳入。F6单步跳过。Ctrl+F2终止。

//断点
断点右键可设置断点属性,定义断点的条件。

//生成get,set
高亮字段,如_NewsId,右键,源代码,生成Getter/Setter

//List(array)和 Tree(xml)的绑定
<mx:List x="20" y="20" dataProvider="{array_data}" width="180"></mx:List>
<mx:Tree x="20" y="200" labelField="@label" dataProvider="{myData}" width="180"></mx:Tree>

//常用布局组件
Canvas(自由布局)、VBox(垂直布局)、HBox(水平布局),默认状态下滚动条采用自动适应的原则。
Panel具有Canvas、VBox和HBox 的所有功能。如果Panel的layout属性值为“absolute”,则Panel对子级元素的布局方式和Canvas一样;当值为 horizontal时相当于HBox,值为vertical则相当于VBox。
TitleWindow组件继承于Panel组件,与Panel 相比,它只多了一个关闭按钮。关闭事件为close。
Grid可以像Table一样使用,单元格也有colSpan和rowSpan。
Accordion 组件:一个可折叠的导航器,它包含一个子面板的列表,一次仅显示一个面板,可切换。
ViewStack组件:由若干个重叠在一起的子容器组成,每次只有一个容器是可见或活动的。要通过AS代码来控制切换,设置viewstack.selectedChild。
TabNavigator,继承自ViewStack,类似ajax的tab控件。

//事件查看和生成
选中控件,点击菜单栏“窗口”“属性”,在属性窗口中,选择“按字母排序视图”。

//form表单控件
通过 FormItem快速部署了一个用户信息表单。对表单的验证:
<mx:StringValidator source="{user_txt}" property="text" minLength="6" maxLength="12" tooShortError="用户名太短了"/>  //自定义提示取代默认提示
<mx:StringValidator source="{pass_txt}" property="text" minLength="6" maxLength="12"/>  //默认提示
<mx:PhoneNumberValidator source="{phone_txt}" property="text"/>  //电话验证
<mx:DateValidator source="{birth_txt}" property="text"/>  //日期验证
<mx:EmailValidator source="{email_txt}" property="text"/>  //email验证

//DataGrid组件
<mx:DataGrid ... dataProvider="{books.book}">...<mx:columns><mx:DataGridColumn dataField="name" headerText="书名"/>...   //Model的id为books
在 DataGrid组件中使用itmeRenderer(加入自定义控件):...<mx:DataGridColumn headerText="购买" itemRenderer="view.cartCell"/>...
除了itemRenderer,同样可以自定义的还有headerRenderer和itemEditor,前者控制标题栏的界面,后者控制单元格在编辑状态下的界面(DataGrid的 editable为true时)

//Tree组件
<mx:Tree ... dataProvider="{files}" labelField="@label" change="treeChange(event)"... />  //XMLList的id为files;
public function treeChange(event:Event):void { selectedNode = Tree(event.target).selectedItem as XML; txt.text = selectedNode.@label; }

//TileList组件
和 List一样,它也支持自定义itmeRenderer。<mx:TileList itemRenderer="ImageItem" ... dataProvider="{images.item}">  //ImageItem是mxml自定义控件

//文件处理
Text、 TextInput和TextArea。Text可以支持html标签(即解释html),不过需要借助htmlText标签(使用时必须含有CDATA 标签)
RichTextEditor编辑器,使用obj.htmlText和obj.text得到文本值。

//导航类控件
ToggleButtonBar 和TabBar,dataProvider为Array。ViewStack的定义:
<mx:ViewStack id="myViewstack" ...>
 <mx:Canvas id="child1" ...>...</mx:Canvas>
 <mx:Canvas id="child2" ...>...</mx:Canvas>
 <mx:Canvas id="child3" ...>...</mx:Canvas>
</mx:ViewStack>

//menuBar组件
以特定格式的xml对象作为数据提供者,如<node label="清除画板" data="clear" enabled="false"/>,使用MenuEvent.item.@data取得选择值。

//PopUpButton和 PopUpMenuButton
PopUpButton可以将任何组件作为窗口弹出,置于最上层。主要事件有 PopUpButtion.open()和PopUpButton.Close()。
PopUpMentButton是前者的一个特例,它只能把 Menu控件当作弹出窗口。Menu控件用来创建菜单,相比MenuBar,它缺少了菜单条,而且没有对应的MXML标签,只能由代码创建。

/*Flex事件机制*/
as3.0全部采用addEventListener方法来注册监听器,且监听器必须是函数,监听器的作用域和监听器所在对象的作用域一致。
EventDispatcher对象负责实现事件模型,它提供了三个关键的函数来运作事件机制:addEventListener、 removeEventListener和dispatchEvent(派发)。
DisplayObject作为一切可视化元素的父类,直接继承于EventDispatcher对象,也就是说,as3.0中所有可视化对象都具有派发事件的功能。

事件流运行流程分为三步:捕获事件、检测目标的监听器、事件冒泡。
默认情况下,捕获功能处理关闭状态。另外,事件只在bubbles属性为true时才进行冒泡,可以冒泡的事件包括:change、click、doubleClick、keyDown,keyUp、mouseDown、mouseUp。

不可以在一个监听器中同时打开捕获和冒泡功能。要做到这一点,只能注册两个监听器,一个打开捕获功能,一个打开冒泡功能,比如:
canvas1.addEventListener(MouseEvent.CLICK,pressBtn,true);
canvas1.addEventListener(MouseEvent.CLICK,pressBtn);

evt:MouseEvent,evt 对象的四个属性:target表示派发事件的目标对象,currentTarget表示事件流当前正经过的目标对象;bubbles表示是否打开了冒泡功能;eventPhase则表示事件流当前的阶段,1表示捕获,2表示检测,3表示冒泡。

addEventListener(type:String,listener:Function,useCapture:Boolean=false,priority:int=0,useWeakReference:Boolean=false)
//useCaptrue 表示是否打开捕获功能,默认为false;priority表示监听器优先级,默认为0;useWeakReference指定是否使用弱引用,默认为 false。

当综合使用MXML标签和AS来给同一个对象注册监听器时,很难确立这些监听器之间的前后顺序,即无法控制监听函数的执行顺序。如果事件的执行需要按照某一个顺序来进行时,可以使用 addEventListener方法的priority参数来实现(数字越大,级别越高),如:
btn.addEventListener(MouseEvent.CLICK,press1,false,1);
btn.addEventListener(MouseEvent.CLICK,press2,false,4);
btn.addEventListener(MouseEvent.CLICK,press3,false,2);
注意,给一个对象注册多个监听器,即使第个监听器的优先级别不同,但也无法保证后一个执行时前面的监听函数已经执行完毕。因此,在设计程序时,后面的函数不应该以前者执行完毕为条件,最好让各个监听器互相独立。

Flash Palyer的垃圾回收机制:
将已经不再使用的对象清除,释放所占的内存资源,提高程序的运行效率。它的运行有自己的规律,而且是周期性的,并不会在第一时间(比如你把一个对象设为null的时候)将系统中的垃圾资源清理,它通常是在系统资源匮乏的情况下才进行。
如果在对象注册监听器的时候(addEventListener时)默认使用了强引用,Flash Player为了保证程序的运行,会在内存中保留这个对象。即使把它设成null,也只是表面上被删除,实际还是留在内存中,成为一个“幽灵”。
要避免“幽灵”,在注册监听器时,应该养成使用弱引用的习惯,同时,要使用预先定义的函数作为监听函数,而不是临时定义的函数(var f:Function = function():void { ... })。

//拖曳事件(List控件为例)
List1.dragEnabled = true;  //可拖
List1.dropEnabled = true;  //可放
List1.dragMoveEnabled = true;  //不出现重复数据,只调整元素位置

/*第6章 使用行为对象和动画效果*/

<mx:Move id="myMove" target="{img}" xFrom="50" xTo="150" duration="2000"/>  //移动id为img的图片控件,从x坐标50到150,用时2秒

private function initUI():void{
 Effect_Blur.targets = [myPanel];  //模糊对象id是myPanel
}
<mx:Blur id="Effect_Blur" effectEnd="endBlur()" blurXFrom="0" blurXTo="30" blurYFrom="0" blurYTo="30" duration="1500"/>
internal function endBlur():void{
 if(handlerEnd){
  isReverse = !isReverse;  //反向变化
  Effect_Blur.play(null,isReverse);     
 }
}
Effect_Blur.resume();  //继续
Effect_Blur.pause();  //暂停
Effect_Blur.end();  //停止
Effect_Blur.play();  //播放

private function initUI():void{ Effect_Glow.target = myPanel;}  //发光对象
<mx:Glow id="Effect_Glow" alphaFrom="1.0" alphaTo="0.3" blurXFrom="0.0" blurXTo="30.0" blurYFrom="0.0" blurYTo="30.0" color="ox6633ff"/>
Effect_Glow.play();  //播放
myPanel.filters = [];  //停止,将新的数据赋予对象,新的滤镜生效

var newResize:Resize = new Resize();  //缩放图片
newResize.heightFrom = 200;  //设定高度和宽度的起始值
newResize.widthFrom = 200;
newResize.heightTo = 240;  //高度的最终值
newResize.widthBy = 40;  //宽度增加40相当于 widthTo = 240
newResize.hideChildrenTargets = [Panel_1,Panel_2];  //指定要隐藏内部元素的Panel,缩放时隐藏p1和p2
newResize.target = Canvas_1;  //缩放对象
newResize.duration = 2000;  //持续时间  
newResize.addEventListener(TweenEvent.TWEEN_END,myEndHandlerFun);  //监听动画的结束事件

/*第9章 数据绑定*/

//Canvas背景绑定取色器:
<mx:Style source="style.css"/>  //引用样式文件
<mx:ColorPicker id="mColor" x="30" y="30"/>  //取色器
<mx:Canvas styleName="box" id="box" x="30" y="80" backgroundColor="{ mColor.value.toString() }" width="200" height="160"></mx:Canvas>

//数据绑定
使用大括号是实现数据绑定的最快捷方式。只需要将源数据对象放在大括号中,作为目标对象的值就可以了。
<mx:TextInput id="name_txt" x="89" y="10" width="133"/>
<mx:Text x="89" y="115" text="{name_txt.text}" width="133"/>  //以name_txt.text为数据源,即时更新
<mx:Script>
 <![CDATA[
  [Bindable]  //标识数据源
  internal function ShowAge(s:String):String{
   var n:Number = Number(s);
   if(n>=16) return "成年";
   return "未成年";
  }
 ]]>
</mx:Script>
<mx:Text x="89" y="150" text="{ShowAge(age_txt.text)}" width="133"/>

//使用<mx:Binding>
好处在于,可以将数据绑定和描述界面的MXML代码分离开来,使得程序结构井井有条。
<mx:Model id="users">  //数据源对象
 <users><user><name>Peter Ent</name></user></users>
</mx:Model>
<mx:Label id="name_txt" x="10" y="135" width="154"/>
<mx:Binding source="users.user.name" destination="name_txt.text" />  //id.item.property

//绑定类对象
[Bindable]
public class myTest{
 public var className:String = "";
}
<tree:myTest id="test"/>  //使用MXML标签定义非可视化类对象,在initApp或在点击时为属性赋值
<mx:Label id="tip_txt" x="0" y="20" title="{test.className}"/>

如果组件是程序创建的(如上面的 test是new出来的),那就要用:
BindingUtils.bindProperty(tip_txt,"title",test,"className");  //将test的className和tip_txt的title属性绑定
BindingUtils.bindSetter(setName,test,"className");  //将test的className属性和setName函数绑在一起,setName参数是一个string,参数值是test的className

//派发事件
在类中,可以通过属性的setter派发,如在myTest类中:
[Bindable("NumChange")]  //属性可绑定,定义了一个NumChange事件
public function set Num(n:Number):void{
 if(num != n){
  num = n;
  this.dispatchEvent(new Event("NumChange"));  //派发事件
 }
}
在主程序里可以添加监听:
test = new myTest(); 
test.addEventListener("NumChange",handler);  //当test的num被赋值时会触发handler函数

注意,数组类型的对象,其子元素是无法作为数据源参与绑定的。如不能期望一个文本控件绑定到array中某一个元素。
Object类实例不能实现绑定,因为Object类型属于动态类型,我们可以随意地向里面添加任何属性,而且属性的类型也是任意的,编译器很难正确识别这些属性和属性的数据类型。要解决这个问题,需要使用 mx.utils包中的ObjectProxy对象。

//定义绑定类
[Bindable]
public class people
{
 public var name:String;
 public var email:String;
 public var img:String;
 
 function people(obj:Object):void{  //构造函数
  for(var i:String in obj){
   this[i]  = obj[i];
  }
 }
}

/*第10章 组件的使用*/
// 应用样式
//使用主题
//修改组件外观
//创建组件

/*第11章 Flex2.0新特性实例开发*/
//处理XML
//example one
private var myData:XML = <items>
              <item type = "流行音乐"><song>每一刻都是崭新的</song></item>
              <item type = "古典音乐"><song>拉德斯基进行曲 </song></item>
              <item type="乡村音乐"><song>光阴的故事</song></item>
             </items>;

internal function initApp():void{
source_txt.text = myData.toXMLString();  //字符串输出
output(" 节点数目:"+myData..item.length());  //myData.child("item").length(),输出3

for (var prop:String in myData..item){  //var prop:String in myData.child("item"),prop是节点的索引,0,1,2
 var node:XML = myData..item[prop];  //myData.child("item")[prop]
   output("节点:"+prop);
   output("属性名:"+String(node.@type));  //node.attribute("type")
   output(" 子节点:"+node.song);  //node.child("song")
   output("----------");
}
output(myData..item.(@type == "流行音乐"));  //属性type
output(myData..item.(song != "光阴的故事").song);  //节点song

//example two
var xml:XML = new XML("<items></items>");  //定义根
var node:XML = <item type = "流行音乐"><song>每一刻都是崭新的</song></item>;
xml.appendChild(node);  //添加节点
node = <item type = "古典音乐"><song>拉德斯基进行曲 </song></item>;
xml.insertChildBefore(xml..item.(@type == "流行音乐"),node);  //插入节点
var tmp:XML = node.copy();  //复制节点(含节点值)
tmp.@type = "乡村音乐";  //重新赋值(覆盖原值)
tmp.song = "光阴的故事";
xml.appendChild(tmp);
output(xml.toXMLString());

//example three
internal function initApp():void{
  var loader:URLLoader = new URLLoader();
 loader.load(new URLRequest("http://rss.sina.com.cn/news/allnews/sports.xml"));  //返回请求的页面信息(源代码)
 loader.addEventListener(Event.COMPLETE, completeHandler);  //完成事件
 loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
 loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
 CursorManager.setBusyCursor();  //鼠标等待
}
internal function completeHandler(evt:Event):void{
 CursorManager.removeBusyCursor();  //移除等待
 var myXML:XML = XML(evt.target.data);  //类型转化
 parseRSS(myXML);  //输出
}
internal function parseRSS(xml:XML):void{
 var items:ArrayCollection = new ArrayCollection();  //结果集
 for(var i:String in xml..item){
  var node:XML = xml..item[i];  //结点
  var obj:Object = new Object();  //实体
  obj.title = node.title;
  obj.link = node.link
  obj.pubDate = node.pubDate;
  obj.description = node.description;
  items.addItem(obj);
 }
 newsList.labelField = "title";  //显示字体
 newsList.dataProvider = items;
}
internal function showNews():void{  //<mx:List id="newsList" width="100%" change="showNews()"></mx:List>
 var item:Object = newsList.selectedItem;
 news_txt.htmlText = "<b><a href='"+item.link+"'>"+item.title+"</a></b><br/>";
 news_txt.htmlText += "发布日期:"+item.pubDate+"<br/><br/>";
 news_txt.htmlText += item.description+"<br/>";
}

/*第11章 Flex2.0新特性实例开发*/
//正则表达式
//声音控制
//Socket通信

《Flex 第一步》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 爬虫:Scrapy16 - Spider Contracts

    Scrapy 通过合同(contract)的方式来提供了测试 spider 的集成方法. 可以硬编码(hardcode)一个样例(sample)url,设置多个条件来测试回调函数处理 response ...

  2. php 数据库内容增删改查----增

    首先,建立一个主页面(crud.php) <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  3. try...catch 语句

    一般情况下,我们很少用到 try...catch 语句,但是有时候为了测试代码中的错误,也有可能会用到.小白我也在工作中用到过.那么好的程序设计,什么时候会用到呢? try...catch 一般用来捕 ...

  4. [GDOI2016] 疯狂动物园 [树链剖分+可持久化线段树]

    题面 太长了,而且解释的不清楚,我来给个简化版的题意: 给定一棵$n$个点的数,每个点有点权,你需要实现以下$m$个操作 操作1,把$x$到$y$的路径上的所有点的权值都加上$delta$,并且更新一 ...

  5. Spring和ActiveMQ集成实现队列消息以及PUB/SUB模型

    前言:本文是基于Spring和ActiveMQ的一个示例文章,包括了Point-To-Point的异步队列消息和PUB/SUB(发布/订阅)模型,只是做了比较简单的实现,无任何业务方面的东西,作为一个 ...

  6. 让chrome支持本地Ajax请求

    Chrome的安全机制不能支持ajax的本地访问, 例如: 在JavaScript里面访问 URL:file:///E:/test.html,Chrome 浏览器报错:XMLHttpRequest c ...

  7. IEjs 调试、火狐 js 调试

    http://www.jb51.net/article/26707.htm IE下调试代码, 在代码中写 debugger; 然后IE启用调试, 会执行到debugger 断点出, 双击变量 右键 添 ...

  8. 理解javascript的闭包,原型,和匿名函数及IIFE

    理解javascript的闭包,原型,和匿名函数(自己总结) 一 .>关于闭包 理解闭包 需要的知识1.变量的作用域 例1: var n =99; //建立函数外的全局变量 function r ...

  9. 百度之星复赛T5&&hdu6148

    Problem Description 众所周知,度度熊非常喜欢数字. 它最近发明了一种新的数字:Valley Number,像山谷一样的数字. 当一个数字,从左到右依次看过去数字没有出现先递增接着递 ...

  10. 战斗机的祈雨仪式(NOIP模拟赛Round 7)

    [问题描述] 炎炎夏日,如果没有一场大雨怎么才能尽兴?秋之国的人民准备了一场祈雨仪式.战斗机由于拥有操纵雷电的能力,所以也加入了其中,为此,她进行了一番准备. 战斗机需要给自己的Spear of Lo ...