Flash mx 2004 V2组件架构I[高级]

作者: egoldy

性质: 翻译

阅读次数: 11985

发表时间: 2005-04-10 17:05:14


Flash mx 2004 v2 组件的架构----简介

声明:本教程出处于http://www.ultrashock.com,英文版权归ultrashock所有。谢决转载 。



此篇文章介绍的是v2组件的构架,以及讨论作为一个MM V2组件开发人员应当熟知的一些概念。当你在创建组时,可以选择使用Macromedia V2 构架,也可以使用传统的movie clip class方式。在创建组件时如果你想要你的组件与MM自已的组件相互兼容,那么使用V2构架和类是很重要的。另外一个好处是Macromedia已经对 V2组件投入了很大的努力来定时加更新V2架构,大多数组件有在公共部分是相同的。开发人员可以把重点放在组件的定义上,这样即使是新的组件开发人员在开 发时也会很觉得使用V2架构要比直接使用movie Class要自然的多。

注意:此文针对的是 2.0.0.377版本的V2组件架构,在你工作前应先要检查一下你所用的V2架构版本,这是很重要的。如果你使用的是新的。应先查看相关的更新信息文 档。此版本的V2组件架构适用于Flash MX 2004 (7.0.0 and 7.0.1),如果你用的是flashmx2004 7.2,你需要先查看一下相关说明文档。

组件架构的基础类---UIObject 和 UIComponent

V2组件架构中有两个很重要的类,就是mx.core.UIObject和mx.core.UIComponent.
UIObject 是MovieClip的子类,它包括了大多数的构架功能的定义。UIComponent是UIObject的子类。它是我们在创建组件时需要经常用到的类。
此教程最先介绍UIObject,然后转向计论UIComponet,掌握好UIObject对于理解UIComponent和V2架构是至关重要的。

I. Setup and core implementatiion(设置和执行核心)

UIObject 是一个MovieClip的子类,因此当你在创建一个标准的MovieClip类时要确保你的库中有针对此类的元件。通常如果你只是要创建一个与标准的 MoiveClip相关联的类,你需要创建元件并使用库与类相关联.当你的组件从UIObject继承时,你需要做一些额外的工作来确保所有的架构包含在 你的组件中,你可以在这里找到创建设置component的细节的FLA(http://www.ultrashock.com/tutorials/flashmx2004/components.php

开始时,我们将写一个最基本的组件类的结构,这个类与你库中的元件相关联。
例如:

 

import mx.core.UIObject;
class com.rewindlife.controls.TextBox extends UIObject
{
}; 


上面的例子示范了一个空的component,它不能做任何事性,这个文件必须要存在一个适当的结构目录中,并且命名为:TextBox.as

注意:如果你已经使用或是计划在某些点上使用Meadata tags,你需要注意导入“import mx.core.UIObject”这一行。在原理上,你应使用完全路径类名称来引用UIObject。然而,如果你计划想要正确的继承Metadata Tag 定义,flashmx 2004 环境需要你导入扩展的类.因为这个,一个最好的习惯是总是导入父类。Metadata tags 是用来描述我们的组件所拥有的能力的。这方面的知识我们不在此教程中讨论,但是你可以在这里找到相关的详细资料,http://livedocs.macromedia.com/flash/mx2004/main/05_cre29.htm

a.Required Properties(需要的属性)

当使用UIObject做为一个基础类时,你的组件必须以正确的变量来声明或定义属性。
SymbolName(元件名称)

“symbolName” 属性应设为库中元件的linkage(链接)名称以用于你的component组件,当在运行时贴加(attachement)你的组件实例至舞台时,这 个属性被用于createClassObject()方法从库中找到正确对应的元件。如果在你的库中有一个相应的MovieClip(component symbol), linkage链接名为“YourComponent”,那么这个就是你要设置给属性的变量。


例如:

 

public static var symbolName:String = "com.rewindlife.controls.TextBox"; 



注意小心你的component linkage ID的名字,Macromedia 在他们的所有component组件使用类名称做为linkage ID.尽管这样工作的很好,当你决定跟随MM的习惯使用类名时,你的linkage ID名称与库中的其它的元件符号冲突时,你仍可能会陷入困境。在先的flash版本中,组件开发人员一般为他们的元件符号冠以高贵的前缀如Mr等用于他们 独有的ID.例如,你在开发自已的按钮组件,你可以使用“wsButton”, 或”cn.com.webstudio.controls.Button”.我更喜欢使完全路径类名方式,但这只是个人的观点。我明确的反对使用如 “Button“名字,因为它已经被应用于Macromedia button component,你可能也会希望最大程度让你的组件与Macromedia组件愉快的共处,Macomedia也将建议你将来使用完全路径类名 (fully packaged)方式。

symbolOwner(元件拥有者)

“symbolOwner”属性也是createClassObject()需要的一个属性,它被用于当component动态贴加 (attachment)过程。组件构架通过组件的元件符号使用Object.registerClass()与symbolOwner连接。你仍需要设 置明确的变量为完全路径类名。

例如:

 

public static var symbolOwner:Object = com.rewindlife.controls.TextBox; 



className (类名称)

“className”属性不要必需的但你无论如何你要指定它,因此我把它在这段里。这个属性用于在组件架构中执行getStyle()方法.如 果style样式被设置在_global.[className]那么getStyle()将在适当的时候识别它返回它的值。大多数情况下这个属性的名字 是不正规的类名尽管你可能觉得其它的组件会使用相同的类名,而要决定使用一个更独立的ID。例如,如果你在创建一个新的按钮组件,你可能想要让它唯一而使 用象”myButton” 做为这个类名。

例如:

 

private var className:String = "YourComponent"; 


clipParameters & mergedClipParameters(剪辑参数和合并剪辑参数)

当一个组件初始化时,如果它包含有setter方法并且在组件未完全初始化完之前被调用,这些setter方法在flash player 6的某些环境中不能完全完成定义,如果你使用的是flash player 7,那么你可以忽略这个条件,通常认为始终包含它是一个好的习惯。
例如:

 

/*
更新需要的属性的代码需要包在com.rewindlife.controls
*/
import mx.core.UIObject;
class com.rewindlife.controls.TextBox extends UIObject
{
  public static var symbolName:String = "com.rewindlife.controls.TextBox";
  public static var symbolOwner:Object = com.rewindlife.controls.TextBox;
  private var className:String = "TextBox";

  //你指定的每个setter属性
  private var clipParameters:Object = {someSetter:1,someOtherSetter:1};
  //确保包含有对mergeClipParameters()的静态调用,它的功能是合并两个类(组件)r的//clipParameters,一个是你传递的类的引用的clipParameters,另一个是父类的//clipParameters.
//Make sure to include the static call to mergeClipParameters(). What this function
  //does is merge the clipParameters of two classes (components)
  //You pass it a reference to this class’s clipParameters, and the parent class’s
  //clipParameters.
  private static var mergedClipParameters :Boolean =
  UIObject.mergeClipParameters(TextBox.prototype.clipParameters,
                               UIObject.prototype.clipParameters);
};



你实际上不用为当组件架构在场景后方工作时的具体情况而给我们带来什么。如果你对组件的初始化时发生了什么感兴趣,那么就请继续读完。

为了理解下面代码为什么必需,它到底做了些什,最首要要理解的问题是什么,这个问题围饶在flash player 6中通过代码创建的动态MovieClip实例。在FLASH player 6中如果你使用createClassObject()或是attachMovie()来例示你的组件,并且将它传递给initObject,这个 initObject包含有setter属性变量,那些setter方法将不被调用。而是属性被设置给instance实例,当setter定义变得可用 时就会很快的被擦去。这将导致属性值丢失。

 

createClassObject(mx.controls.Button,"myButton",1,{label:"Hello World"});
//LABEL属性从未被调用 


这个问题已经在flash player 7得到了修正,但是因为在许多时候我们想要将创建的组件发布成flashplayer6,那么组件架构给我们提供了一个解决方法。

这个解决方法包括为你提供的一系列component(clipParameters)包含的setter 属性列表.它会通知组件架构处理那些可能调用失败的情况(当你调用super.init()时它会被处理).之前你已经创建拥有他们setter属性的基 础类,你使用mergeClipParameters()来合并当前类的clipParameters和父类的clipParameters.下一步,因 为属性值被设定在setter是可用状态之前,组件架构将存储那些属性值以用于后来使用。最后,当setter变为可用时,组件架构将自动的调用 setter并且传递所存储的值。

b. Initialization, required methods and a bit of theory (b.初始化,需要的方法和一点原理)

当组件初始化时有几件事情会发生,是否有对将要发生在组件生命点的事情有好的认识对创建有效的组件是至关重要的。
从之前的教程(http://www.ultrashock.com/tutorials/flashmx2004/components.php),你可能记得你的组件有init(),createChildren(),和draw()方法。你可能没有意识到这些方法是怎样被自动调用的。当一个类是UIObject的子类,这些方法当组件被例示时会被调用。你需要了解他们调用的顺序和每一个是做什么的。

Component initialization order:(组件初始化顺序)


I.   init() method (init()方法)
II. createChildren() method(createChildren()方法)
III. a single frame passes, it’s important to keep this in mind at times (一个单一的结构传递,它是很重要需要注意)
IV. draw() method (draw()方法)

I.init()

init()方法通常是你的组件第一个执行的方法,在init()方法中你必须始终调用super.init().它将调用UIObject的 init() 执行,它将设定在组件的架构中,这个方法在组件初始时只调用一次。这个方法的另一个目的是创建成员变量。所有组件需要例示的实例变量在此时完成。 MovieClips和TextFields(sub_Object)在init()时不被例示.

II. createChildren()

在这个方法中,你将创建和配置所有的子对象(MovieClip subclasses).sub-object是绘制嵌套对象就象MovieClips或是TextFields.等其它组件。在理论上,当创建sub- object,你应当在适当的时候使用createClassObject(),和createLabel().你可能使用attachMovie()和 createTextField(),但明智的做法是你在组件内部使用组件架构提供的方法,createClassObject()是一个方便的通过类名 引用组件的方法。还有createLabel(),由UIObject提供是创建可以自动继承组件样式的TextField的好方法。你可能已经很熟悉了 createClassObject(),createLabel()在这个教程中被隐的较深,在这个方法中你可能想为你的组件设置一些不在组件形成过程 中更改的初始属性,这个方法在初始时只被调用一次。

III. Invalidation

Invalidation是架构提供的核心特性,初始化过程中,在开始时组件是无效的,它的转变过程需要调用draw()方法,你可能要想为什么 我们需要无效,它的好处在哪,最好的解释就是我们看一下例子,假设用户在单一帧中为若干属性设定若干变量和调用若干方法时,每一个都在转变时调用 draw()方法以确保组件的新的数据形态显示出来。通常情况下一个属性被设定或一个方法被调用时都要调用一次draw()方法,这样会使你的 draw()方法在单一帧中被调用多次,在FLASH中,在每一帧上只绘制一次用来更新当前的显示状态,因此在单一帧上不需要立即或多次绘制来显示状态, 取而代之最好的方法是当所有的调用结束后将多次调用转为调用一次draw()方法,不仅仅是因为它浪费资源而且还会在频繁调用draw()方法时有可能会 出现问题。这就是invalidation的解决方法。使用invalidation,所有的属性设定和方法调用被储存以在后面更新使用,然后在单一帧上 调用invalidation()方法,V2架构将在一帧上巩固所有的调用在下一帧上调用draw()方法,因此使执行更加有效。Draw()方法将用于 存储那些变量(通常是指model状态)来更新显示状态。Invalidate()方法对于所有的UIObject子类sub-object是可用的。并 且对于组件的初始化是可靠的。
另一个优点是当你自已的代码不是很可靠时调用invalidate()方法。例如支持样式,组件架框可以很好的为我们处理,任何时候当用户设定样式,你的组需要知道它,组件架构将暗中无效你的组件,以确保draw()方法被调用。

Without invalidation(没有使用无效)

With invalidation(使用无效)

椐上面的知识,你不需要直接调用draw()功能,而是调用invalidate(),有许多时候你可能需要组件立即重绘,如果是这样你可以通调 用redraw(true)来告诉你的组件立即重绘。那么现在你可能想知道为什么在你需要立即重绘组件时不能直接调用draw()方法,而是去调用 redraw(true)。Invalidation过程需要invalidateFlag属性被设置为true才可以调用draw()方法,当 draw()方法被调用完成后事件广播才对所有的侦听器进行广播。所有这些都是为了照顾invalidate()或是redraw(true),我们稍后 看到其它事件与draw()的执行不同之处,你可能还想验证在UIObject中执行redraw()功能到底会发生什么。

IV. draw()

Draw()方法一般用在当你的组件被发现时更新显示状态。从上面的讨论中,我们知道无论何时组在invalidate/redraw时都将被调 用,当写入这个方法时,非常重要的一点是它通常是最后被调用的方法在组件初始化过程中。并且在你组件每将状态改变时调用。因为此,你必须确何这个方法对你 的组件是有效的,而不使你的组件受到其它的影响。

Other Important Methods to Implement (其它重要的执行方法)
size()


尽管这个方法不在例示的时候被调用,但在你的组件执行过程中会经常用到它,并且在编写组件时要不断的考虑到它。当setSize()被调用 时,size()方法被暗中调用。你的组件执行size()方法只是处理组件的大小而不做其它事情,为确何你的组件有效执行你必须确保你的设置大小的代码 与它的draw()方法分开,如果你在创建一个小的组件不需要什么逻辑,你可以决定将你的设置大小代码放置在draw定义中并且从size()方法中调用 invalidate(),它不会有什么错误出现,但是如果你的组件相对比较复杂,你需要改变大小和调用invalidate()来重绘组件,或在 size()方法执行设定组件大小的逻辑,最后你不要调用从draw方法调用size()方法,因为它会产生一个无穷循环。Size方法有两个可用的属 性,__width和__height属性,这些属性体现用户设定的宽和高。你可以使用这两个属性设定新的宽高值,你还可能使用oldWidth和 oldHeight属性值,它将做为没有需要改变属性值之前的设定。


讨论此教程

服务项目_SERVICE

关于我们

万博思图(北京)信息技术有限公司,专业的flash,flex开发团队,5年经验。公司致力于互联网上的业务的开展,对于互动网站行销,互联网应用程序开发有成熟的解决方案。我们关注互联网市场动态,关注新技术,更注重在新的领域不断探索发现。
万博思图业务内容主要包括企业品牌Flash网站开发,企业形象宣传Flash设计,动画,多媒体演示,Flex企业级应用程序开发,拥有众多成功案例,欢迎来电咨询。
 
COPYRIGHT BY WEBSTUDIO INTERACTIVE DESIGN Co.,Ltd. ALL RIGHTS RESERVED.
公司地址: 北京市朝阳区朝外SOHO D 座727室 邮编: 100026 EMAIL: WEBSTUDIO@WEBSTUDIO.COM.CN
电话: 010-59070059 / 010-86390986-802  手机: 13693660520 传真: 010-59070059-801
京公网安备:110108006741      京ICP备08002333号-4
王先生