我需要基于 UIComponent 构建一个新的 UI 控件。控件的高度应该与宽度有一定的比例,并且还取决于显示的内容(内部文本的数量)。有人可以推荐我应该怎么做吗?
我试过用谷歌搜索,但似乎所有文章都试图避免谈论这个案子。我个人的感觉是,Flex 渲染的方式,即失效和更新显示列表,在处理这种情况时本身就效率低下。
以下是我的代码。一切正常,但似乎这不是最有效的方法,因为高度是在 updateDisplayList() 内部计算的,这会触发另一个 updateDisplayList()。
该控件在移动项目内部使用,因此当设备旋转时,父级的大小将发生变化,并且控件也需要调整大小。
所以,有几个问题:
- 在 measure() 中我应该做什么?由于高度基于实际宽度,因此在 updateDisplayList() 之前我无法获得最终宽度,因为控件的父级将宽度定义为百分比。
- 在 updateDisplayList() 的最开始计算高度是否正确?如果没有,我该怎么做?
下面是我的意思的一个例子。
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import mx.core.UIComponent;
public class MyControl extends UIComponent
{
public function MyControl()
{
super();
}
public var textPadding:Number = 15;
public var heightRatio:Number = 1.61803398875;
private var _label:String;
private var labelChanged:Boolean = false;
public function get label():String
{
return _label;
}
public function set label(value:String):void //can be long text with about 20-30 lines
{
if (_label != value)
{
_label = value;
labelChanged = true;
invalidateProperties();
invalidateSize();
invalidateDisplayList();
}
}
private var text:TextField;
override protected function createChildren():void
{
super.createChildren();
if (!text)
{
text = new TextField();
text.autoSize = TextFieldAutoSize.LEFT;
text.multiline = true;
text.wordWrap = true;
addChild(text);
}
}
override protected function commitProperties():void
{
super.commitProperties();
if (labelChanged)
{
text.text = label;
labelChanged = false;
}
}
override protected function measure():void
{
super.measure();
//What should I do here?
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
text.width = unscaledWidth;
if (text.height < unscaledWidth / heightRatio)
{
height = unscaledWidth / heightRatio + textPadding * 2;
}
else
{
height = text.height + textPadding * 2;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
text.x = textPadding;
text.y = textPadding;
}
}