Apache flex 在Flex3的渲染器中,mx:Canvas是如何测量的?
我在HBox内的画布上遇到了尺寸问题。看起来“_graphic”、“_border”和“_fill”画布(在com.example.ThingRenderer.mxml中)与渲染器内的所有其他测量值不同时进行测量。但是,此问题仅在第一次通过时观察到。请参阅图像以了解视觉效果。。。第一幅图显示应用程序完成加载后的状态。第二幅图像表示单击Apache flex 在Flex3的渲染器中,mx:Canvas是如何测量的?,apache-flex,flex3,Apache Flex,Flex3,我在HBox内的画布上遇到了尺寸问题。看起来“_graphic”、“_border”和“_fill”画布(在com.example.ThingRenderer.mxml中)与渲染器内的所有其他测量值不同时进行测量。但是,此问题仅在第一次通过时观察到。请参阅图像以了解视觉效果。。。第一幅图显示应用程序完成加载后的状态。第二幅图像表示单击填充按钮后屏幕的外观。第三幅图显示了步进器递增时发生的情况。问题是,为什么在将数据填充到表中后,第三个图像中的图形不会被渲染 RenderTest.mxml <
填充
按钮后屏幕的外观。第三幅图显示了步进器递增时发生的情况。问题是,为什么在将数据填充到表中后,第三个图像中的图形不会被渲染
RenderTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="handleCreationComplete(event)"
>
<mx:Script>
<![CDATA[
import com.example.Thing;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.events.NumericStepperEvent;
private const _thingProvider:ArrayCollection = new ArrayCollection();
private var _thing1:Thing;
protected function handleCreationComplete(event:FlexEvent):void {
_thing1 = new Thing("thingy", 0xff0000, 0.3);
_stepper.value = _thing1.ratio;
}
protected function handlePopulateClick(event:MouseEvent):void {
_thingProvider.addItem(_thing1);
}
protected function handleStepperChange(event:NumericStepperEvent):void {
_thing1.ratio = event.value;
}
]]>
</mx:Script>
<mx:VBox>
<mx:Button label="Populate" click="handlePopulateClick(event)" />
<mx:NumericStepper id="_stepper" minimum="0" maximum="1" stepSize="0.01" change="handleStepperChange(event)" />
<mx:AdvancedDataGrid dataProvider="{_thingProvider}" variableRowHeight="true" width="100%" height="100%">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="Name" dataField="name" />
<mx:AdvancedDataGridColumn headerText="Display"
width="150" sortable="false"
itemRenderer="com.example.ThingRenderer"
/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:VBox>
</mx:Application>
所有这些都是因为无法在updateDisplayList中使用宽度和高度属性,它们尚未更新。制作单独的组件(例如ThingProgressBar)并将drawing logick放入其中,这将解决所有问题:
package
{
import mx.core.UIComponent;
public class ThingProgressBar extends UIComponent
{
private var _ratio:Number;
public function get ratio():Number
{
return _ratio;
}
public function set ratio(value:Number):void
{
_ratio = value;
invalidateDisplayList();
}
override protected function updateDisplayList(
unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
graphics.clear();
if (unscaledWidth > 0 && unscaledHeight > 0)
{
graphics.lineStyle(1, 0xFF0000);
graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, unscaledWidth * ratio, unscaledHeight);
graphics.endFill();
}
}
}
}
因此,渲染器可能如下所示:
<mx:HBox
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
horizontalScrollPolicy="off" verticalScrollPolicy="off" xmlns:local="*"
>
<fx:Script>
<![CDATA[
[Bindable] private var _thing:Thing;
override public function set data(value:Object):void
{
_thing = value as Thing;
super.data = value;
}
]]>
</fx:Script>
<mx:HBox width="100%"
paddingLeft="5" paddingTop="5"
paddingRight="5" paddingBottom="5">
<mx:Label text="{_thing.name}" width="45" />
<local:ThingProgressBar width="100%" height="15"
ratio="{_thing.ratio}"/>
</mx:HBox>
</mx:HBox>
我玩了大约30分钟,感到很沮丧。我认为,fill.width和border.width返回为0。我不知道它为什么会这样做。因为列表组件(和子类)明确地设置了宽度,而不是宽度(出于某种原因)。我可以看出您所说的是一个合法的解决方案,但是为什么在updateDisplayList函数中_容器(包装mx:Canvas的mx:HBox)的大小是正确的?这是混淆和误导-一些组件的大小和一些不。。。知道为什么吗?@Andrey,看看BoxLayout或Canvas内部,它们在更新期间使用两对函数和属性进行操作:getExplicitOrMeasuredWidth/Heights()和percentWidth/Height,而不是width/Heights本身。当容器布局它的子容器时,它不会影响它的子容器,相反,它们将在LayoutManager中排队等待布局,并将在以后更新(甚至可能在下一帧中)。所以,当您试图在updateDisplayList中检查孙子的大小时,它仍然是零或以前的值。这一切现在都有意义了。谢谢你的回答!
package
{
import mx.core.UIComponent;
public class ThingProgressBar extends UIComponent
{
private var _ratio:Number;
public function get ratio():Number
{
return _ratio;
}
public function set ratio(value:Number):void
{
_ratio = value;
invalidateDisplayList();
}
override protected function updateDisplayList(
unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
graphics.clear();
if (unscaledWidth > 0 && unscaledHeight > 0)
{
graphics.lineStyle(1, 0xFF0000);
graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, unscaledWidth * ratio, unscaledHeight);
graphics.endFill();
}
}
}
}
<mx:HBox
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
horizontalScrollPolicy="off" verticalScrollPolicy="off" xmlns:local="*"
>
<fx:Script>
<![CDATA[
[Bindable] private var _thing:Thing;
override public function set data(value:Object):void
{
_thing = value as Thing;
super.data = value;
}
]]>
</fx:Script>
<mx:HBox width="100%"
paddingLeft="5" paddingTop="5"
paddingRight="5" paddingBottom="5">
<mx:Label text="{_thing.name}" width="45" />
<local:ThingProgressBar width="100%" height="15"
ratio="{_thing.ratio}"/>
</mx:HBox>
</mx:HBox>