Flex4动态加载和切换CSS

Flex4中动态加载CSS文件的方式已经和Flex3有了一定的区别

主要步骤如下:

1.编写不同的CSS文件

见后文

2.将CSS文件编译成SWF文件

在FlashBuilder中右键CSS文件,选择Compile CSS to SWF,
浏览完整全文 »

漫步PureMVC(一) 极简入门

PureMVC官方网站http://puremvc.org/有详细的多语言帮助文档(包括中文)和demo,
但即使是最简单的demo,也要建立N多类,很多朋友都抱怨PureMVC上手机要需要建立太多类,比较难入门
因此我做了下面这个Demo,只用了3个类,来说明PureMVC中Facade和View/Mediator的用法,
以及如何发送和响应notification
并且在以后的blog中,我会在这个demo基础上,逐步添加新的类和功能,逐步深入讲解PureMVC
Demo中有三个朋友列表,分别是全部朋友列表与组A/组B,添加/删除朋友时会同时添加/删除全部列表和指定组的列表
仅包含三个类:
FrinedList.mxml : 主程序,实例化多个MyList.mxml作为朋友列表,向Facade注册mediator,发送添加朋友的通知
views/MyList.mxml : 朋友列表的可视化组件,发送删除朋友的通知
views/MyListMediator.as : MyList.mxml的中介器,响应各种通知,控制MyList.mxml

主程序:FriendList.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"
			   xmlns:views="views.*"
			    creationComplete="application1_creationCompleteHandler(event)">

	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;

			import org.puremvc.as3.multicore.interfaces.IFacade;
			import org.puremvc.as3.multicore.patterns.facade.Facade;

			import views.MyListMediator;

			protected var facade:IFacade = Facade.getInstance('');//获取Facade的单例

			protected function application1_creationCompleteHandler(event:FlexEvent):void
			{
				cbTypeId.textInput.editable = false
				//
				facade.registerMediator(new MyListMediator('all',this.list0));
				facade.registerMediator(new MyListMediator('group1',this.list1));
				facade.registerMediator(new MyListMediator('group2',this.list2));
				//添加几个个测试数据
				this.addNewFriend('Sven',1);
				this.addNewFriend('Lina',2);
				this.addNewFriend('Viper',1);
				this.addNewFriend('Chen',2);
				this.addNewFriend('Zeus ',4);//添加一个特殊typeId的组,测试例外数据的处理
			}

			protected function btnAdd_clickHandler($event:MouseEvent):void{
				this.addNewFriend(this.textName.text,this.cbTypeId.selectedItem.typeId);
				this.textName.text='';//清空名称输入栏,以免连续点击
			}

			protected function addNewFriend($name:String,$typeId:int):void{
				var $friend:Object = new Object();//创建一个新朋友的数据对象
				$friend.name = $name;//设置名称
				$friend.typeId = $typeId;//设置typeId
				facade.sendNotification('add',$friend);//发送通知
			}
		]]>
	</fx:Script>

	<s:HGroup>
		<s:Label text="Name:"/>
		<s:TextInput id="textName"/>
		<s:ComboBox id="cbTypeId" labelField="label" selectedIndex="0">
			<s:dataProvider>
				<s:ArrayCollection>
					<fx:Array>
						<fx:Object label='组A' typeId='1'/>
						<fx:Object label='组B' typeId='2'/>
						<fx:Object label='不分配组' typeId='0'/>
					</fx:Array>
				</s:ArrayCollection>
			</s:dataProvider>
		</s:ComboBox>
		<s:Button enabled="{this.textName.text!=''}" id="btnAdd" label="添加新Friend" click="btnAdd_clickHandler(event)"/>
	</s:HGroup>
	<views:MyList id="list0" x="10" title="全部好友" typeId="0" width="180" top="39" height="486">
	</views:MyList>
	<views:MyList id="list1" x="198" title="组A" typeId="1" width="180" top="39" height="213">
	</views:MyList>
	<views:MyList id="list2" x="198" title="组B" typeId="2" width="180" top="305" height="220">
	</views:MyList>
</s:Application>

朋友列表组件:views/MyList.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group 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="400" height="300"
		  >

	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;

			import org.puremvc.as3.multicore.patterns.facade.Facade;

			[Bindable]
			public var title:String = '';

			public var typeId:int = 0;

			[Bindable]
			public var dataAC:ArrayCollection = new ArrayCollection();

			protected function btnDel_clickHandler(event:MouseEvent):void
			{
				if(this.list.selectedItem){
					Facade.getInstance('').sendNotification('delete',this.list.selectedItem);
				}
			}
		]]>
	</fx:Script>
	<s:Label text="{title}"/>
	<s:List id="list" dataProvider="{dataAC}" top="24" bottom="24" width="100%" labelField="name"/>
	<s:Button id="btnDel" enabled="{this.list.selectedItem}" label="删除所选" click="btnDel_clickHandler(event)" bottom="0" />
</s:Group>

中介器:MyListMediator.as

package views
{
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	public class MyListMediator extends Mediator
	{
		public function MyListMediator(mediatorName:String=null, viewComponent:Object=null)
		{
			super(mediatorName, viewComponent);
		}
		private function get view():MyList{
			return this.viewComponent as MyList;
		}
		//可以接受的通知name
		override public function listNotificationInterests():Array{
			return ['delete','add'];
		}
		//响应通知
		override public function handleNotification(notification:INotification):void{
			var $friend:Object = notification.getBody();//获取通知的内容
			if(this.view.typeId==0 || this.view.typeId==$friend.typeId){
				//所持有的MyList如果是全部朋友的列表或指定typeId的列表,则执行以下操作,否则不执行
				switch(notification.getName()){//区分名称
					case 'delete':
						var $index:int = this.view.dataAC.getItemIndex($friend);
						this.view.dataAC.removeItemAt($index);//告知data删除指定friend object
						break;
					case 'add':
						this.view.dataAC.addItem($friend);//添加frined object
						break;
				}
			}
		}
	}
}

源文件下载 PureMvcDemoFriendList20100511.zip

Flex中的Base64加解密

Flex sdk3就内置了Base64的加/解密工具类
分别是
mx.utils.Base64Encoder
mx.utils.Base64Decoder

Base64Encoder用法如下:
var $orgin:String = this.textOrigi.text;//获取原始字符串
var $base64:Base64Encoder = new Base64Encoder();
$base64.insertNewLines = false;//该值等于true时,输出的结果会自动换行,默认为true,
$base64.encodeUTFBytes($orgin);//这里注意,如果想加密中文就不要使用$base64.encode();
var $result:String = $base64.toString();//输出结果
Base64Decoder用法如下:
				var $origi:String = this.textEncodeResult.text;//获取原始字符串
				var $base64:Base64Decoder = new Base64Decoder();
				$base64.decode($origi);
				var $result:String = $base64.toByteArray().toString();//输出结果,decode类只能输出ByteArray类型的数据,因此要转换成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">

	<fx:Script>
		<![CDATA[
			import mx.utils.Base64Decoder;
			import mx.utils.Base64Encoder;
			protected function btnEncode_clickHandler(event:MouseEvent):void
			{
				var $orgin:String = this.textOrigi.text;//获取原始字符串
				var $base64:Base64Encoder = new Base64Encoder();
				$base64.insertNewLines = false;//该值等于true时,输出的结果会自动换行,默认为true,
				$base64.encodeUTFBytes($orgin);//这里注意,如果想加密中文就不要使用$base64.encode();
				var $result:String = $base64.toString();//输出结果
				this.textEncodeResult.text = $result
			}

			protected function btnDecode_clickHandler(event:MouseEvent):void
			{
				var $origi:String = this.textEncodeResult.text;//获取原始字符串
				var $base64:Base64Decoder = new Base64Decoder();
				$base64.decode($origi);
				var $result:String = $base64.toByteArray().toString();//输出结果,decode类只能输出ByteArray类型的数据,因此要转换成string
				this.textDecodeResult.text = $result
			}

		]]>
	</fx:Script>

	<mx:Form width="100%">
		<mx:FormItem label="原始字符串:" width="100%">
			<s:TextArea editable="true" id="textOrigi" width="100%" text="在这里输入原始字符串"/>
		</mx:FormItem>
		<mx:FormItem>
			<s:Button id="btnEncode" label="Encode Base64" enabled="{this.textOrigi.text!=''}" click="btnEncode_clickHandler(event)"/>
		</mx:FormItem>
		<mx:FormItem label="Encode 结果:" width="100%">
			<s:TextArea editable="false" id="textEncodeResult" width="100%"/>
		</mx:FormItem>
		<mx:FormItem>
			<s:Button id="btnDecode" enabled="{this.textEncodeResult.text!=''}" label="Decode Base64" click="btnDecode_clickHandler(event)"/>
		</mx:FormItem>
		<mx:FormItem label="Decode 结果:" width="100%">
			<s:TextArea editable="false" id="textDecodeResult" width="100%" text="点击Decode Base64按钮后,这里的结果应该和原始字符串相同"/>
		</mx:FormItem>
	</mx:Form>
</s:Application>

FlexBuilder中使用代码片断工具

1.1 工具介绍

使用代码片断工具,您可以存储内容(文档中重复出现的代码如public function …( ):void{   }等)以便快速重复使用。多种软件都含有此工具(例如Dreamweaver),flexbuilder中此工具包含在CFEclipse插件中。

1.2 安装与使用

安装步骤:

a.  帮助       安装新软件;

b.  使用(W)一栏中输入地址   http://www.cfeclipse.org/update

c.  输入网址后按Enter,程序连接服务器,窗口显示“暂挂中”,连接完毕后窗口会显示出可供安装的程序,选择CFEclipse CFML Editor   点 下一步

d.  点 完成  开始下载   出现安全警告提示软件未签名 点击确定  之后按提示重启flex builder

e.  打开工具窗口(Snip Tree View);

f.   编辑代码片断   新建片断

g.  按钮插入该片断(只适用于AS代码文件)

h.  片断中适用参量:$${    }   如图中代码

在插入该片断时会出现提示框,要求输入$${}标记的参数值name  如图

确定后整段代码被插入

Air/Flex动态加载module及其依赖的RSL

有关Flex和Air中如何使用RSL网上教程很多,google一下即可,这里不多做叙述了

而这次遇到的问题是这样的:

发布时只发布一个主程序(Web或者Air方式),而不发布所需要的module及其依赖的swc,只在运行时根据需要加载module及其依赖的swc

1.       建立一个实验用的module工程:

先准备一个module工程,普通的Flex Project(web)即可,主程序名无所谓,因为这个工程只是为了编译module对象用的

在Properties->Flex Build Path中引入所要依赖的swc,这个例子中使用了TweenLite.swc

注意AIR project的默认Link TypeMerge into code,改成RSL。如图:

新建一个包modules并新建一个module程序:MyModule1.mxml

到Properties->Flex Modules中修改该module的optimize属性为none,如下图

点击Edit按钮,弹出下图

选择Do not optimize(…)

在MyModule1.xml中使用TweenLite做一个简单的动画:

TweenLite.to(<strong>this</strong>.goed,4,{x:500});

编译工程,

此时MyModule1.mxml被编译生成为MyModule1.swf

TweenLite.swc会被编译成TweenLite.swf

复制到要被加载的目录下,我的是

http://127.0.0.1/testflex/TweenLite.swf

http://127.0.0.1/testflex/modules/MyModule1.swf

2.       建立主工程(Flex Web):

新建一个Flex Project(web),不要使用引入TweenLite.swc

新建一个用来控制加载TweenLite的类:

tasks/TaskLoadRSL.as

在这个类中,使用URLLoader将TweenLite.swc从http://127.0.0.1/testflex/TweenLite.swf上加载下来,主要代码如下:

var loader:Loader = new Loader();
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;//必须有这一句,RSL必须和主程序在同一个域中
loader.load(new URLRequest(this.web),context);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,localLoadCompleteHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,localLoadIoErrorHandler);

加载完TweenLite后不需要任何操作,直接开始加载module即可

使用IModuleInfo或ModuleLoader加载module都可以,详见源代码

3.       建立主工程 (AIR):

Air中比Flex要麻烦,因为发布时只发布主程序,所以运行时需要先检测本地是否有swc和

module

如果有就直接加载运行(同Web)

如果没有就从网站上下载到本地,然后再加载

主要代码如下:

从网络地址上加载:

var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, loadFromWebCompleteHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, loadFromWebErrorHandler);
loader.load(new URLRequest(web))

加载完,保存到本地:

var loader:URLLoader = URLLoader($e.target);
var data:ByteArray = ByteArray(loader.data);
var file:File = new File(File.applicationDirectory.resolvePath(this.local).nativePath);
trace('save file to' + file.nativePath);
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeBytes(data);
fileStream.close();
this.loadFromLocalFile();

本地加载过程同Flex Web

更多内容参加源代码:DynamicTestLoadModuleAndRSL

httpservice request传参数的几种方式

mxml代码中 httpservice 组件,连接一php计算器

<s:Button click="this.hs.send();"/>
<fx:Declarations>
	<s:HTTPService id="hs" url="http://127.0.0.1/cal.php" method="GET">
		<s:request xmlns="">
			<calculator>plus</calculator>
			<param1>10</param1>
			<param2>23</param2>
		</s:request>
		<s:fault>
			<![CDATA[
				trace("")
			]]>
		</s:fault>
		<s:result>
			<![CDATA[
				trace(event.result.result.equals)
			]]>
		</s:result>
	</s:HTTPService>
</fx:Declarations>

httpService组件,在as块中传入参数

var param:Object = {calculator:"minus",param1:"23",param2:"13"}
httpServ.send(param)

<mx:HTTPService id="httpServ">
	<mx:resultFormat>text</mx:resultFormat>
	<mx:url>http://127.0.0.1/cal.php</mx:url>
	<mx:fault>Alert.show(event.toString(), event.type);</mx:fault>
</mx:HTTPService>

as代码中,使用httpservice类

public var httpservice:mx.rpc.http.HTTPService = new mx.rpc.http.HTTPService();
public var param:Object={calculator:"minus",param1:"23",param2:"13"};
public function send_data():void{
	httpservice.url ="http://127.0.0.1/cal.php";
	httpservice.method = "POST";
	httpservice.addEventListener(ResultEvent.RESULT, resultHandler);
	httpservice.addEventListener(FaultEvent.FAULT, this.HttpErrorHandle);
	httpservice.send(param);
		}

as代码中使用urlloader

public function Temp()
		{
			var url:String = "http://127.0.0.1/cal.php"
			var urlVariables:URLVariables = new URLVariables();
			urlVariables.decode("calculator=plus&param1=10&param2=22");
			var request:URLRequest = new URLRequest(url);
			request.data = urlVariables;
			request.method = URLRequestMethod.POST

			var loader:URLLoader = new URLLoader()
			loader.dataFormat = URLLoaderDataFormat.TEXT
			loader.addEventListener(Event.COMPLETE, onComplete)
			loader.load(request);

		}
		public function onlistener(event:Event):void{
			var xml:XML = new XML(event.target.data)

			trace(xml..equals)
		}

偶遇FLEX 4中容器之间复制数据方法

偶遇书上容器之间的复制数据方法。通过拖拽功能实现不同容器间的数据复制,能优化交互功能。小试成功,令闻此方法可能小有用处,故将此方法发于此,方便大家讨论及指正。主要代码如下所示。

在.mxml中添加组件:

<s:HGroup>
<s:HGroup>
<s:Label text="可选专辑" fontSize="14"/>
<mx:DataGrid id="srcgrid" dragEnabled="true" fontSize="12">
<mx:columns>
<mx:DataGridColumn dataField="Artist" headerText="Singer"/>
<mx:DataGridColumn dataField="Album" headerText="Album"/>
<mx:DataGridColumn dataField="Price" headerText="Price"/>
</mx:columns>
</mx:DataGrid>
</s:HGroup>
<s:HGroup>
<s:Label text="已经选购的专辑" fontSize="14"/>
<mx:DataGrid id="destgrid" dropEnabled="true" fontSize="12" dragDrop="destgrid_dragDropHandler(event)">
<mx:columns>
<mx:DataGridColumn dataField="Artist1" headerText="Singer"/>
<mx:DataGridColumn dataField="Album1" headerText="Album"/>
<mx:DataGridColumn dataField="Price1" headerText="Price"/>
</mx:columns>
</mx:DataGrid>
</s:HGroup>
</s:HGroup>

fx:Script中的代码:

protected function application1_creationCompleteHandler(event:FlexEvent):void     //createcomplete函数,为datagrid赋值
{
srcgrid.dataProvider = new ArrayCollection([
{Artist:'English',Album:'Learn',Price:1},
{Artist:'Chinese',Album:'Try',Price:3},
]);
destgrid.dataProvider = new ArrayCollection();
// TODO Auto-generated method stub
}

protected function destgrid_dragDropHandler(event:DragEvent):void     //拖拽时调用的方法
{
if (event.dragSource.hasFormat("items"))
{
event.preventDefault();                         //取消默认行为

//获取拖放的目标对象
var droptarget:DataGrid = DataGrid(event.currentTarget);

//隐藏鼠标下方允许拖放的指示条

droptarget.hideDropFeedback(event);

//获取复制的数据集
var itemsArray:Array = event.dragSource.dataForFormat("items") as Array;

//复制数据
var tempItem:Object = {
Artist1:itemsArray[0].Artist,
Album1:itemsArray[0].Album,
Price1:itemsArray[0].Price
};

//获取拖放的目标对象的位置
var droploc:int = droptarget.calculateDropIndex(event);

IList(droptarget.dataProvider).addItemAt(tempItem,droploc);

}

}

运行效果如下:

AS3中使用Twitter API

自制app使用Twitter API

1.1   准备工作

A.注册Twitter用户

B. 下载库文件http://dev.twitter.com/pages/libraries

本实例使用ActionScript 库文件 TwitterScript http://code.google.com/p/twitterscript/

C. Twitter官方文档 http://dev.twitter.com/doc TwitterScript并无说明文档,Twitter官方的文档和TwitterScript的代码不一致,但不矛盾。

1.2 需求说明

制作AIR程序(图1),实现如下功能

a.  显示当前用户头像,用户名

b.  显示当前用户following   followers

c.  显示当前用户friends Tweet  public Tweet

d.  提交新Tweet,并体现到friends Tweet中

图1 程序界面

1.3编写代码

Twitter数据调用多数需要身份验证,有的是不需要的。

Twitter的身份验证简单,只需将用户名和密码编码后嵌入到实际调用数据的request的requestHeaders中即可(暂不考虑OAuth),不同于facebook须登录后得到session-key才能调用数据。

TwitterScript 中的方法:

类Twitter.as中function setAuthenticationCredentials(“username”,”password”)

此方法只是将用户的名和密码编码,function twitterRequest()负责将编码嵌入到requestHeaders,该嵌入过程被整合到各个具体调用数据的方法中因此编写程序代码时不用考虑此过程

A.制作登录页面,通过TextInput将用户名密码传给程序。(图2)

图2

提示:两个state ,登录界面和程序界面两个界面大小可以不同:代码如

<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" width="800" height="500"
					   currentState="sign_out" width.sign_out="320" height.sign_out="230"
					   width.sign_in="628" height.sign_in="500">

Sign in按钮click=“sign_in( )”

B. 定义sign_in方法,调用数据

var twitter:Twitter = new Twitter()

twitte.setAuthenticationCredentials(usrId.text, passwd.text)

对用户名 密码编码, userId 和 passwd是登录页面两个输入框的ID

twitter.loadInfo(userId.text)

twitter.addEventListener(TwitterEvent.ON_SHOW_INFO, onloadInfo)

调用user信息

twitter.loadFriends(usrId.text)

twitter.addEventListener(TwitterEvent.ON_FRIENDS_RESULT, onloadfriends)

调用user following

twitter.loadFriendsTimeline(userID.text)

twitter.addEventListener(TwitterEvent.ON_FRIENDS_TIMELINE_RESULT, onloadUserTimeLine)

调用friends Tweet

twitter.addEventListener(TwitterEvent.ON_ERROR, onerror)

监听error

C. 处理返回结果。制作程序界面(如图3)

图3

a.显示用户名 头像

loadInfo方法返回的data类型为TwitterUser,包含name ,square url等,处理方法略

b.显示following用户名

loadFriends方法返回TwitterUser的Array

var tmp:Array = event.data as Array

for (var i:int; i<tmp.length; i++){

var user:TwitterUser = tmp[i];

followname.addItem({flwname:user.name})

followname:ArrayCollection 绑定为显示following 的List的数据源,List标签中建itemrenderer 代码如

<fx:Script>
		<![CDATA[

			[Bindable]
			public var displayname:String;
			override public function set data(value:Object):void{

				displayname = new String(value.flwname)

			}
		]]>
	</fx:Script>
	<s:VGroup>
			<s:Label text="{displayname}"/>
	</s:VGroup>

提示:也可显示头像、创建时间、时区等等

c.显示user ‘s friends Tweet   public Tweet

loadFriendsTimeline方法返回Tweet的Array包含text 和发布者信息等

var tmp:Array = event.data as Array;

for(var i:int;i<event.data.length;i++){ tweetArray.addItem(tmp[i])}

tweetArray:ArrayCollection绑定为显示tweet的DataGrid的数据源,DataGrid代码

<mx:DataGrid x="10" y="87" width="607" height="327" dataProvider="{tweetArray}">
			<mx:columns>
				<mx:DataGridColumn headerText="Tweet" dataField="text"/>
				<mx:DataGridColumn headerText="Tweeter" dataField="user.name" width="100"/>
			</mx:columns>
		</mx:DataGrid>

d.  提交新Tweet。添加输入框和提交按钮,按钮事件sendTweet()

public function sendTweet():void{

var Tweet:String = tweet.text

将输入内容赋值给变量Tweet

twitter.setStatus(Tweet);

提交Tweet

twitter.addEventListener(TwitterEvent.ON_SET_STATUS, onsetstatus)

监听是否成功

tweet.text = “”} 将输入框中文本清除

提交成功后onsetstatus方法刷新一下DataGrid的数据 定义刷新方法

function freshTweet()本例将loadFriendsTimeline方法提出另定义为LoadFriendsTimeLine方法,function freshTweet()执行LoadFriendsTimeLine方法。

e.  添加刷新按钮  添加button 定义skinClass=“com.skin.freshButton”按钮图存同一路径 freshButton 代码

<s:states>
		<s:State name="disabled" />
		<s:State name="down" />
		<s:State name="over" />
		<s:State name="up" />
	</s:states>
	<s:BitmapImage source="@Embed('arrow_refresh.png')"/>

按钮 buttonmode=“true”click=“freshTweet()”

f.   添加Alert.Show 。之前监听Error的响应方法 编写代码

var alert:Alert = Alert.show(“something was wrong,click button for try again”)

登录页面 检验是否输入用户名密码

if(userId.text==”"||passwd.text==”"){ Alert.show(“please enter your username and password!”)}

2 Twitter官网工具

API Status    查看各API状态

http://dev.twitter.com/status

API Console     Web Console

http://dev.twitter.com/start

Bug:Flex自动帧频1000!

用Flex4才发现了这个问题,

当用spark添加一个mx组件时不会有问题,但当这个mx组件中还有其他组件

例如<mx:HBox><mx:Canvas/></mx:HBox>

stage.frameRate会瞬间达到1000!

之后会自动恢复到默认的帧频(如果不手动设定,会是24)

这时不用担心什么问题,

但如果frameRate达到1000的这段时间中,添加了一个EnterFrame事件,

并且在EnterFrame的响应函数中,调整某个组件的位置,

frameRate就不会恢复回24,而是一直持续1000,知道取消了EnterFrame为止

源文件:
src
源码如下:
Application.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" frameRate="12"
			 backgroundColor="0xFF00FF">
	<fx:Script>
		<![CDATA[

			import components.MyComponent;

			import mx.containers.HBox;
			import mx.core.UIComponent;
			import mx.events.FlexEvent;

			protected function button2_clickHandler(event:MouseEvent):void
			{
				trace(this.stage.frameRate);
				this.txt.text = "Current FrameRate:"+this.stage.frameRate.toString();
			}

			protected var _box:UIComponent;
			protected function button3_clickHandler(event:MouseEvent):void
			{
				_box = new MyComponent();
				this.container2.removeAllElements();
				this.container2.addElement(_box);
				button2_clickHandler(null);
				button4_clickHandler(null);
			}

			protected function enterFrameHandler(event:Event):void
			{
				if(_box){
					container1.x+=0.2;
				}
			}
			protected function button4_clickHandler(event:MouseEvent):void
			{
//				this.moveEffect.play([this.container2]);
				this.addEventListener(Event.ENTER_FRAME,this.enterFrameHandler);
			}
			protected function button5_clickHandler(event:MouseEvent):void
			{
				this.removeEventListener(Event.ENTER_FRAME,this.enterFrameHandler);
			}

		]]>
	</fx:Script>

	<fx:Declarations>
		<s:Move id="moveEffect" duration="10000" xFrom="10" xTo="300" yFrom="10" yTo="300"/>
	</fx:Declarations>
	<mx:Canvas id="container1" y="60" width="100%" height="100%"/>
	<s:SkinnableContainer id="container2" x="20" y="80" width="900" height="600"/>

	<s:Group>
		<s:layout>
			<s:HorizontalLayout>
			</s:HorizontalLayout>
		</s:layout>
		<s:Button click="button2_clickHandler(event)" label="Trace frameRate"/>
		<s:Label text="" id="txt" width="100"/>
		<s:Button click="button3_clickHandler(event)" label="load MyComponent"/>
		<s:Button click="button4_clickHandler(event)" label="Start Move"/>
		<s:Button click="button5_clickHandler(event)" label="Stop Move"/>
	</s:Group>
</s:Application>

components/MyComponent.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox 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:Canvas backgroundAlpha="1" width="30" height="30" backgroundColor="0x0000F0"/>
</mx:HBox>

as3中正则表达式符号说明与使用

元字符:^ $ \ . * + ? ( ) [ ] { } |

^   匹配字符串的开头

$    匹配字符串的结尾

\    转义字符,用于元字符

*    0或多个前面的字符

+   至少一个前面的字符

?    0或1个前面的字符

.     任意单个字符 except newline

[]   某个范围的单个字符

()   集合

|    或运算,匹配左或右

元序列:

{n}      恰好匹配n个前面的

{n,}     匹配至少n个前面的

{n,m}   匹配至少n个,至多m个前面的

\b        匹配只能放在前面或结尾

\B        与\b相反

\d        数字

\D        数字以外的

\w        单词字符(A-Z、a-z、0-9 或 _)

\W       除单词字符以外的任何字符

\unnnn       字符代码由十六进制数字 nnnn 指定的 Unicode 字符(\u263a ☺)

\xnn           具有指定 ASCII 值(由十六进制数字 nn 定义)的字符。

\s        任意空白字符(空格、制表符、换行符或回车符)

\S        除空白字符以外的任何字符

\n        换行符

\r         回车符

DOS中专用的

\v        垂直换页符DOS

\t         制表符DOS

\f         换页符DOS

标志:

g          如果不指定g,那么在查找的时候只会返回一个。

I           默认情况下,匹配区分大小写。如果设置 i (ignoreCase) 标志,将忽略区分大小写

m         匹配”行”的开头和结尾.注意这里的行只有\n字符表示行的结束,其余不行,包括\r

s          用点来匹配换行符

x          在正则表达式中使用 x (extended) 标志时,则会忽略在模式中键入的所有空格

附加:

[abc]          character a,b or c

[^abc]       Any character except a,b or c

[a-z]          a through z

[]中‘空格’和\s都可以表示空格符

但[]外只能用\s表示空格符

AS3中声明正则表达式的两种方式

var reg:RegExp = new RegExp(“test-\\d”, “g”);

var reg:RegExp = /test-\d/g;
使用

var str:String = ‘<span>test string</span>’;

str.replace(reg,’-');

str.match(reg);

量词类型

贪婪量词:

先看整个字符串是不是一个匹配。如果没有发现匹配,它去掉最后字符串中的最后一个字符,并再次尝试。如果还是没有发现匹配,那么    再次去掉最后一个字符串,这个过程会一直重复直到发现一个匹配或者字符串不剩任何字符。简单量词都是贪婪量词。

惰性量词:

先看字符串中的第一个字母是不是一个匹配,如果单独着一个字符还不够,就读入下一个字符,组成两个字符的字符串。如果还没有发现匹配,惰性量词继续从字符串中添加字符直到发现一个匹配或者整个字符串都检查过也没有匹配。惰性量词和贪婪量词的工作方式恰好相反。
支配量词:

只尝试匹配整个字符串。如果整个字符串不能产生匹配,不做进一步尝试。
贪婪量词   惰性量词    支配量词                      描述
————————————————————————————-
?             ??             ?+                      可以出现0次或1次,但至多出现1次
*             *?            *+                      可以出现任意次,也可以不出现
+             +?            ++                      出现1次或多次,但至少出现1次
{n}        {n}?           {n}+                   一定出现n次
{n,m}    {n,m}?       {n,m}+               至少出现n次,但至多不能超过m次
{n,}       {n,}?          {n,}+                 可以出现任意次,但至少出现n次

例子:

<bord>test</bord>

使用 /<.*?>/g       结果:    -test-

使用 /<.*>/g     结果:     -