LunaStudio.cn A Group of Passion Creators

21一/120

FLEX4组件的生命周期

发布在 KAN

首先是创建阶段

Construction 构造阶段

呼叫构造函数,这时便可以访问对象的属性和方法了.但这个时候还没有任何子元件产生

Configuration 配置阶段

这个阶段是把外部定义的属性值赋进对象中去的操作.

Addition添加阶段

添加对象到父显示列表中

Initialization初始化阶段

一般是发送一些事件.preInitialize,initialize,creationComplete事件

组件被创建之后,就开始展示给用户,并发挥其功能了

组件的总是伴随着失效,生效,交互,再失效这样的一个循环过程来的

Invalidation失效阶段

当组件的属性发生改变之时,执行invalidateProperties()

当组件的尺寸发生改变时,执行invalidateSize()

当显示列表发生改变时,执行invalidateDisplayList()

当皮肤的状态发生改变时,执行invalidateSkinState()

Validation生效阶段

当属性发生改变,会执行commitProperties().首先会执行此方法

当皮肤状态发生改变时,会调用getCurrentSkinState()获取皮肤的当前状态

当显示列表需要被刷新时,会调用updateDisplayList()

当尺寸发生改变时,会调用measure()重新计算尺寸.该方法会从最里边的元件调用起走.固定尺寸的组件不会被执行此方法

Interaction交互阶段

处理用户交互事件

产生失效操作,以进入再一次刷新的循环

组件的移除

Removal移除阶段

通常就是指组件被从父容器中移除掉.

GC 垃圾回收

使用强类型,使用弱事件监听,注意Object或是dictionary的引用问题

总结:

序列化的失效处理 和 延时的生效操作是组件周期的核心要领.掌握各种生效方法

8一/120

FLEX 4 SKINNING–皮肤中的动态元件

发布在 KAN

SkinnableComponent中的[SKINPART]是用来描述皮肤的部件的.其中有俩参数,一个type,一个required
required为true表示这是个元件是必要元件.默认是FALSE
申明了type然后参数的类型是IFactory,说明这个类型就是一个动态元件了.
例如
[SkinPart(type="spark.components.Button")]
public var buttonFactory:IFactory;
然后这个工厂的定义被放置在了SKIN中,如
<fx:Declarations>
<fx:Component id="buttonFactory">
<s:Button />
</fx:Component>
</fx:Declarations>
从代码中可以看出来,工厂所以产生的实例被放在了一个与[SKINPART]对应的ID的Component中了.
举一反三,我们也可以在这里放入我们自定义的类.或者直接放一个复合的GROUP.例如
<fx:Component id="labelGroupFactory">
<s:Group>
<s:Image id="labelDisplay" />
</s:Group>
</fx:Component>

接下来就是使用它们了
动态元件在组件还存活着生命周期里需要开发者自己来维护它的产生和删除.主要用到方法
createDynamicPartInstance(partName:String):Object

removeDynamicPartInstance(partName:String, instance:Object):void

拿后边的那个复合GROUP来具例.
假设我们的需求是,我们的组件中有一个水平布局的GROUP,现在要放一些标签到其中.然后当我们点标签的时候再把该图片删除
首先我们的SKIN中定义
<fx:Component id="labelGroupFactory">
<s:Group>
<s:Label id="labelDisplay" click="{event.target.owner.dispatchEvent(new Event('removedMe'))}" />
</s:Group>
</fx:Component>

<s:Group id="container" width="100%" height="100%">
<s:layout>
<s:HorizontalLayout />
</s:layout>
</s:Group>

然后是我们的SkinnableComponent

[SkinPart]
public var labelGroupFactory:IFactory;
[SkinPart]
public var container:Group;
......
public function addLabel(label:String):void
{
var c:*=createDynamicPartInstance("labelGroupFactory");
c.labelDisplay.text=label;
c.addEventListener("removedMe",function(e){
removeDynamicPartInstance("labelGroupFactory",e.target);
container.removeElement(e.target);
})
container.addElement(c);
}

然后把SkinnableComponent组件放到主程序中,再随便找个按钮,在点击的时候调用一下addLabel方法做一下测试

总结:动态元件一般用在象类似角色装扮这种,某一个组件的内部元件会变化的情景中.

转贴请注明来自lunastudio.cn

1十二/110

FLEX 4 SKINNING–SkinnableComponent的currentState

发布在 KAN

纯AS的SkinnableComponent类,通过[SkinState]标签申明其SKIN需要准备哪几个场景.
SkinnableComponent本身继承自UIComponent,所以也是有currentState这种属性,但SkinnableComponent的currentState却与SKIN的currentState无关系.换句话说,你需要自己在SkinnableComponent中去维护SKIN的状态改变.(一般不要直接在SKIN中写具体的交互并做状态改变,保证逻辑与交互放在SkinnableComponent中进行,SKIN只是单纯提供视图以及效果)
一般而言,在明确SKIN的状态可能因为某些原因发生改变了之后,便在SkinnableComponent中调用一下invalidateSkinState(),然后在稍后的屏幕更新过程中设置SKIN的新状态.这时,会通过getCurrentSkinState()方法获取新的状态值,所以该方法一般是需要重写的.

如果你觉得很别扭,非要把SkinnableComponent的currentState给利用起来,也不是不可以
1.在SkinnableComponent的构造函数中添加状态声明.例如
this.states.push(new State({name:"stateA"}));
this.states.push(new State({name:"stateB"}));
2.然后覆盖set currentState(value:String):void这个函数
override public function set currentState(value:String):void
{
super.currentState=value;
this.invalidateSkinState();
}
3.然后是修改getCurrentSkinState方法
override protected function getCurrentSkinState():String
{
return this.currentState;
}
这样,当你在外边修改你的SkinnableComponent的状态时,便会同时修改了SKIN的状态

转帖请注明来自lunastudio.cn

23九/110

FLEX中CSS编译成SWF的经验总结

发布在 KAN

为了在FLEX中实现动态样式切换,一般的做法是将CSS编译成SWF之后,再使用

StyleManager.loadStyleDeclarations("css.swf");

这样的方式来实现样式的切换工作.

我们可以在右键CSS文件,然后选择"编译CSS为SWF文件"来实现我们想要的效果.但是有一点注意,如果你的CSS中定义了类似

skinClass:ClassReference("cn.LunaStudio.skins.ImageButtonSkin");

这样的自定义的皮肤指向,编译出来的SWF中会找不到这些自定义的类,所以会在加载CSS.SWF之后使用的过程中报找不到类的错误.

这个时候,你需要把CSS文件放到SRC的根目录下,然后你就会发现编译出来的类便正常地包含了自定义的类了,然后一切正常了

21八/110

Flex中的方法绑定的一个比较实际的小例子

发布在 KAN

我们知道[Bindable]标签是可以直接针对事件的绑定.就象下边这样子
[Bindable("myChangeEvent")]
public var myProp:*;
当该对象发送myChangeEvent的时候,myProp的绑定便生效了,这时,与myProp建立的绑定关联,也就跟着更新了.
对于方法绑定,其效果是一样的,也就是说,我同样也可以把上边的代码变成
[Bindable("myChangeEvent")]
public function myFunc(myProp:*):*{...}
根据这一点特性,我们可以做一些比较实际点的应用.比如I18N的立即切换内容的解决方案
如下边的例子
______________________________

Sorry, either Adobe flash is not installed or you do not have it enabled

右键查看源文件

______________________________

参考:

http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff3.html

http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7cc5.html

25七/110

定义发布用的NetStream需要使用实例域变量,局部变量者无效

发布在 KAN

1
2
3
4
5
6
import flash.net.NetStream;
var nc:NetConnection;
var video:Video;
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.connect("rtmp://localhost/livestreams");
1
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 function netStatusHandler(event:NetStatusEvent):void
{
trace(event.info.code);
switch (event.info.code)
{
case "NetConnection.Connect.Success":
publishLiveStream();
break;
case "NetStream.Publish.Start":
var ns2:NetStream=new NetStream(nc);
ns2.play("testStream")
video1.attachNetStream(ns2);
break;
}
}
//try comment this line;尝试注释这一行,把NS变成局部变量
var ns:NetStream;
function publishLiveStream():void {
//if u comment the above line,uncomment this line;把NS变成局部变量,你会发现发布视频失效了
// var ns = new NetStream(nc);
ns = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
ns.attachCamera(Camera.getCamera());
ns.publish("testStream", "live");
}
30五/110

U3D-island demo(sfs-version)

发布在 KAN

最近开始折腾起U3D了.把官方提供的ISLAND的DEMO从原来的SFS1移植到SFS2X上,运行良好

访问地址
http://218.240.54.69:8080/island/index.html
输入IP的时候将127.0.0.1换成218.240.54.69

18四/110

使用poeditor建立或更新po文件

发布在 KAN

上一篇帖子中描述了通过xgettext制作PO文件的一些方法,其实我们也可以用poeditor来很方便地生成PO文件
具体操作如下边的图所示
文件->新建消息文档



文件保存在工程的目录下(和src文件夹同级别)
文件->首选项

点击如图的按钮,更新翻译字段

最后就取得了所有AS文件中需要翻译的字段了

当AS文件中有新的翻译字段时,只需打开PO文件,再点一下更新源就可以了.

当然,如果你还是想使用命令行去操作,在这里的更新PO文件的时候,就要用到msgmerge命令.详情可参考此链接说明

转帖注明出处:

http://lunastudio.cn

4四/110

在FlashBuilder中使用getText

发布在 KAN

首先,是要装备一些必要的软件和代码
安装getText

http://gnuwin32.sourceforge.net/packages/gettext.htm

推荐安装"安装版",在安装完后,记得把getText的bin目录添加到path中去

安装PoEditor

http://www.poedit.net/download.php

下载As3GetText

http://code.google.com/p/actionscript3gettext/

然后在程序中需要翻译的文字前用一个特殊的方法名做为提取翻译字句的依据,一般来说,是用
__("helloworld");
用一个或两个"_"用做方法用.
然后在打开cmd
输入如下的指令
xgettext myclass.as --force-po --from-code=utf-8 -p po_dir -L ObjectiveC
这里需要注意的是,一般来说,因为我们给了__方法,只需要通过参数--keyword=__来指名,xgettext就能自动解析出来我们的翻译字典,但不知道是什么原因,没有成功,所幸ObjectiveC的默认识别方法就是__,所以这里只要把-L,即把默认语言改成ObjectiveC就可以正常解出PO文件了.
另外,当我们要去检索复数文件,比如说src目录下的所有as文件的话,需要配合find一起使用
find src -name "*.as" -print >tmplist
xgettext --files-from=tmplist --force-po --from-code=utf-8 -p po_dir -L ObjectiveC

这样就能生成PO文件了.
然后再用POeditor打开PO文件,为这些字符,配上对应的翻译即可

然后刚才提到的__("helloworld")方法的功能就是通过as3gettext里边的API,来读取.po文件所生成的.mo文件语言包,然后再转换成翻译后的语言,这个可以去看一下as3gettext里的sample

最后再说一下一个getText的Eclipse插件

http://www.gted.org/

在FB菜单中,HELP->INSTALL NEW SOFTWARE
然后添加站点

http://gted.sourceforge.net/update

然后安装好后,在WINDOWS->PREFERNENCE里就能找到geted.在path to gettext这指向一开始安装的gettext的bin目录
然后在项目上的属性菜单里找到geted settings里找到相关对应的设置
最后再项目右键菜单里找到geted->update po files,即可生成最一的PO文件了

转帖注明出处:

http://lunastudio.cn

   下一页