createChildren()
createChildren()
在构造函数之后,同时要在组件通过addChild()
函数添加到父组件(或者在 MXML 文件中隐式地被添加)之后被调用。注意,如果你继承的是Group
,那么应该是addElement()
而不是addChild()
。这是由于Group
不支持addChild()
函数。
createChildren()
函数用于实例化你的组件中所有可视化组件,并使用其默认值进行初始化。类似构造函数,createChildren()
也只会被调用一次,所以,这是实例化可视化子元素的好地方。一个好的设计是,如果你的组件需要有很多绘制过程,那么可以把每一个绘制过程作为一个函数,在createChildren()
中依次调用。这样做有两个好处:让你的代码更清晰,并且方便在以后复用这些绘制过程。
在createchildren()
函数中放置所有可视化组件的实例化,并不一定要直接把初始化好的组件加到父组件中。如果你的子组件只在用户点击或者鼠标滑过时才会被显示出来,那么,在createChildren()
实例化完成之后直接添加显然是一种浪费。建议的做法是,仅仅完成相应的初始化操作,在需要的时候才被添加到DisplayList
中。需要注意的是,不要让你添加的组件影响到用户的使用。所有组件都是添加到一个类似堆栈的显示列表中,后添加的组件将覆盖掉前面添加的。因此,小心你的组件遮挡住用户输入等等这类问题。
commitProperties()
commitProperties()
函数用于处理组件能够被外部代码影响到的属性的修改等的操作。例如使用 MXML 设置Button
的label
值:
<s:Button label="Hello World" />
此时,Button
的label
属性的值变成 Hello World。label
属性的 set 、get 函数将被调用,这将通知组件框架,重新计算属性值。为达到这一目的,invalidateProperties()
将被调用。这个函数并不会马上改变属性值,而是做一标记,告诉组件框架,在下一帧里面重新计算属性值,因为有值被改变了。到了下一帧的时候,commitProperties()
被调用,label
才会被真正修改成 Hello World。
每一个可视元素的属性或者大小被修改之后,可能会触发一系列的更新操作。所有这些更新操作都会被标记,并且在后续的帧里面批量被执行。在上面的例子中,Hello World 要比原来Button
的label
值长,因此,invalidateSize()
函数也会被调用,因为组件需要重新计算其大小。invalidateSize()
会调用measure()
函数,也许还会调用updateDisplayList()
函数。
measure()
measure()
函数与组件生命周期里面的其它函数有些不同。只有组件的width
和height
值没有设置的时候,measure()
函数才会被调用。因此,只要你设置了组件的width
和height
属性,即使你调用invalidateSize()
函数,measure()
也不会被调用,因为你已经制定了大小,Flex 不需要通过measure()
再去计算组件的大小。
measure()
函数的实际工作过程是:当measure()
被调用之后,它首先检查 explicitHeight
和explicitWidth
是否返回NaN
。如果是,则执行函数代码,计算你的组件的width
和height
。现在你会问,这个 explicitHeight
和 explicitWidth
是哪里来的?事实上,Flex 扩展了width
和height
属性,让它们有一组可用值,每一类值都有不同的作用:
类型 | 描述 | 注意事项 |
explicitHeight explicitWidth explicitMaxHeight explicitMaxWidth explicitMinHeight explicitMinWidth explicitHeight explicitWidth | 精确(explicit)值由组件的容器(不是组件本身)使用。它们与很多值相关:组件的实际尺寸、最大尺寸和最小尺寸。这些值由组件的父容器使用,用于计算组件的大小和在容器中的位置。 | 组件的容器使用这些值计算其大小。如果你的组件的父组件是一个基于容器的组件,那么这些可能不会有影响。同样,所有的值都是根据组件的坐标系的,会受到其父组件的影响而有缩放。因此,在系统坐标系下,其值可能也会不同。 |
maxHeight maxWidth minHeight minWidth | 由父容器使用,用于计算组件的尺寸和位置。 | 最大最小值同精确大小类似。这些值的大小也会受到父组件的影响而产生缩放,因此,在不同坐标系下也可能返回不同的值。 |
percentHeight percentWidth | 允许使用百分比的形式定义组件大小。 | 如果你设置了height ,width ,explicitHeight 或者explicitWidth ,这些值将被重置并被忽略。 |
measuredHeight measuredWidth measuredMinHeight meaasuredMinWidth | 用于定义组件的默认大小。这是在measure() 函数中应当设置的唯一属性。 | 无需在外部设置这些属性,在设置width 和height 时,它们将被自动设置。 |
height width | 在外部指定组件大小时所需设置的属性。当它们之中的任何一个被设置时,都会派发一个resize 事件,用于重新计算组件的大小。 | 尽管你可以在 MXML 中设置width="100%" ,但在 ActionScript 中,你必须使用percentWidth 和percentHeight 设置百分比大小。 |
正如上表所示,这些属性中只有几组是供组件自己计算自己的大小。其它都是由组件框架使用,与你的组件不相干。值得注意的是,MXML 代码中并没有percentWidth
和percentHeight
这两个属性。当你在 MXML 中使用width
和height
时,如果你的值是百分比形式,则 Flex 会自动赋值给percentWidth
和percentHeight
,否则赋值给width
和height
。
了解到这些之后,我们如何设置组件大小呢?现在你有几个选择。首先,你可以显式地设置组件的width
和height
。如果你没有设置其中任意一个或者两个都不设,那么这个值就会被初始化为 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()
函数定义组件的默认大小。之后,我们将研究,当用户指定了组件width
和height
的时候,如何设置组件的大小。