理解 Flex 4 组件生命周期(2)

createChildren()

createChildren()在构造函数之后,同时要在组件通过addChild()函数添加到父组件(或者在 MXML 文件中隐式地被添加)之后被调用。注意,如果你继承的是Group,那么应该是addElement()而不是addChild()。这是由于Group不支持addChild()函数。

createChildren()函数用于实例化你的组件中所有可视化组件,并使用其默认值进行初始化。类似构造函数,createChildren()也只会被调用一次,所以,这是实例化可视化子元素的好地方。一个好的设计是,如果你的组件需要有很多绘制过程,那么可以把每一个绘制过程作为一个函数,在createChildren()中依次调用。这样做有两个好处:让你的代码更清晰,并且方便在以后复用这些绘制过程。

createchildren()函数中放置所有可视化组件的实例化,并不一定要直接把初始化好的组件加到父组件中。如果你的子组件只在用户点击或者鼠标滑过时才会被显示出来,那么,在createChildren()实例化完成之后直接添加显然是一种浪费。建议的做法是,仅仅完成相应的初始化操作,在需要的时候才被添加到DisplayList中。需要注意的是,不要让你添加的组件影响到用户的使用。所有组件都是添加到一个类似堆栈的显示列表中,后添加的组件将覆盖掉前面添加的。因此,小心你的组件遮挡住用户输入等等这类问题。

commitProperties()

commitProperties()函数用于处理组件能够被外部代码影响到的属性的修改等的操作。例如使用 MXML 设置Buttonlabel值:

<s:Button label="Hello World" />

此时,Buttonlabel属性的值变成 Hello World。label属性的 set 、get 函数将被调用,这将通知组件框架,重新计算属性值。为达到这一目的,invalidateProperties()将被调用。这个函数并不会马上改变属性值,而是做一标记,告诉组件框架,在下一帧里面重新计算属性值,因为有值被改变了。到了下一帧的时候,commitProperties()被调用,label才会被真正修改成 Hello World。

每一个可视元素的属性或者大小被修改之后,可能会触发一系列的更新操作。所有这些更新操作都会被标记,并且在后续的帧里面批量被执行。在上面的例子中,Hello World 要比原来Buttonlabel值长,因此,invalidateSize()函数也会被调用,因为组件需要重新计算其大小。invalidateSize()会调用measure()函数,也许还会调用updateDisplayList()函数。

measure()

measure()函数与组件生命周期里面的其它函数有些不同。只有组件的widthheight值没有设置的时候,measure()函数才会被调用。因此,只要你设置了组件的widthheight属性,即使你调用invalidateSize()函数,measure()也不会被调用,因为你已经制定了大小,Flex 不需要通过measure()再去计算组件的大小。

measure()函数的实际工作过程是:当measure()被调用之后,它首先检查 explicitHeightexplicitWidth是否返回NaN。如果是,则执行函数代码,计算你的组件的widthheight。现在你会问,这个 explicitHeight和  explicitWidth是哪里来的?事实上,Flex 扩展了widthheight属性,让它们有一组可用值,每一类值都有不同的作用:

类型 描述 注意事项
explicitHeight
explicitWidth
explicitMaxHeight
explicitMaxWidth
explicitMinHeight
explicitMinWidth
explicitHeight
explicitWidth
精确(explicit)值由组件的容器(不是组件本身)使用。它们与很多值相关:组件的实际尺寸、最大尺寸和最小尺寸。这些值由组件的父容器使用,用于计算组件的大小和在容器中的位置。 组件的容器使用这些值计算其大小。如果你的组件的父组件是一个基于容器的组件,那么这些可能不会有影响。同样,所有的值都是根据组件的坐标系的,会受到其父组件的影响而有缩放。因此,在系统坐标系下,其值可能也会不同。
maxHeight
maxWidth
minHeight
minWidth
由父容器使用,用于计算组件的尺寸和位置。 最大最小值同精确大小类似。这些值的大小也会受到父组件的影响而产生缩放,因此,在不同坐标系下也可能返回不同的值。
percentHeight
percentWidth
允许使用百分比的形式定义组件大小。 如果你设置了height,width,explicitHeight或者explicitWidth,这些值将被重置并被忽略。
measuredHeight
measuredWidth
measuredMinHeight
meaasuredMinWidth
用于定义组件的默认大小。这是在measure()函数中应当设置的唯一属性。 无需在外部设置这些属性,在设置widthheight时,它们将被自动设置。
height
width
在外部指定组件大小时所需设置的属性。当它们之中的任何一个被设置时,都会派发一个resize事件,用于重新计算组件的大小。 尽管你可以在 MXML 中设置width="100%",但在 ActionScript 中,你必须使用percentWidthpercentHeight设置百分比大小。

正如上表所示,这些属性中只有几组是供组件自己计算自己的大小。其它都是由组件框架使用,与你的组件不相干。值得注意的是,MXML 代码中并没有percentWidthpercentHeight这两个属性。当你在 MXML 中使用widthheight时,如果你的值是百分比形式,则 Flex 会自动赋值给percentWidthpercentHeight,否则赋值给widthheight

了解到这些之后,我们如何设置组件大小呢?现在你有几个选择。首先,你可以显式地设置组件的widthheight。如果你没有设置其中任意一个或者两个都不设,那么这个值就会被初始化为 0,这样做的效果就是让你的组件变得不可见。当然,你不应该使用这种代码去让你的组件变得不可见,因为有些子组件可能会依赖于父组件的大小,这么做的话很可能让这些子组件显示不正确。第二个方法是设置组件的最小width  和height。这样做的好处是,Flex 知道你不想让你的组件尺寸小于某个值。如果你的 layout 不能很优雅地缩小组件尺寸,或者组件尺寸低于某一个值的时候就会变得不可用时,这样做就会很有效。

override protected function measure():void
{
    measuredHeight = 200;
    measuredWidth = 200;
    measuredMinHeight = 25;
    measuredMinWidth = 100;
}

注意,这么做并不是一种确定的方式,有很多方法可以重载甚至直接忽略这些代码。

很多情况下,这些属性都会被设置为相同的值,如下面代码所示。毕竟,measure()函数的作用就是提供一个默认值,以便用户能够方便地使用你的组件,无需给你的组件显式提供一个默认值。这么做的结果就是,在 FlashBuilder 的设计视图下,组件可以显示一个比较合适的大小。

override protected function measure():void
{
    measuredHeight = measuredMinHeight = 200;
    measuredWidth = measuredMinWidth = 100;
}

现在我们已经了解到如何使用measure()函数定义组件的默认大小。之后,我们将研究,当用户指定了组件widthheight的时候,如何设置组件的大小。

Leave a Reply