flex自定义容器奇怪的自动调整大小行为

时间:2011-11-30 15:39:50

标签: flex resize custom-component

我编写了一个自动调整内容(子)大小的节组件(边框+标题)。

以下是组件代码:

<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                      xmlns:s="library://ns.adobe.com/flex/spark" 
                      xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Declarations>
        <!-- Placer ici les éléments non visuels (services et objets de valeur, par exemple). -->
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            [Bindable]
            public var title:String;
        ]]>
    </fx:Script>

</s:SkinnableContainer>

这是皮肤:

<?xml version="1.0" encoding="utf-8"?>

<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5"
    creationComplete="fitContent(event)">

    <fx:Metadata>
    <![CDATA[ 
        /** 
         * @copy spark.skins.spark.ApplicationSkin#hostComponent
         */
        [HostComponent("component.GlassSectionComponent")]
    ]]>
    </fx:Metadata> 

    <fx:Script>
        <![CDATA[
            import mx.core.UIComponent;
            import mx.events.FlexEvent;

            override protected function initializationComplete():void{
                super.initializationComplete();
                this.contentGroup.addEventListener(Event.ADDED,fitContent,false);
            }

            private function fitContent(event:Event):void{
                this.minHeight = this.contentGroup.contentHeight + this.contentHeight - this.contentGroup.height;
                this.minWidth = this.contentGroup.contentWidth + this.contentWidth - this.contentGroup.width;
                this.invalidateSize();
                this.invalidateDisplayList();
            }
        ]]>
    </fx:Script>

    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- border --> 
    <s:Path id="border" left="3" right="3" top="5" bottom="5"
            data="M 5 0
            L {this.titleDisplay.left-7} 0
            M {this.titleDisplay.left+this.titleDisplay.width} 0
            L {this.width-5} 0
            C {this.width} 0 {this.width} 0 {this.width} 5
            L {this.width} {this.height-5}
            C {this.width} {this.height} {this.width} {this.height} {this.width-5} {this.height}
            L 5 {this.height}
            C 0 {this.height} 0 {this.height} 0 {this.height-5}
            L 0 5
            C 0 0 0 0 5 0
            ">
        <s:filters>
            <s:GlowFilter alpha="0.5" blurX="10" blurY="10" color="0xffffff"
                          quality="5" strength="6"/>
        </s:filters>
        <s:stroke>     
            <s:SolidColorStroke id="borderStroke" weight="1" color="#ffffff" alpha="0.5"/>
        </s:stroke>
    </s:Path>


    <s:Label id="titleDisplay" maxDisplayedLines="1"
             left="{this.width*0.08}" top="0" bottom="0" minHeight="30"
             verticalAlign="top" textAlign="left" fontWeight="bold"
             text="{hostComponent.title}">
        <s:filters>
            <s:GlowFilter alpha="0.5" blurX="10" blurY="10" color="0xffffff"
                          quality="5" strength="6"/>
        </s:filters>
    </s:Label>

    <!--
        Note: setting the minimum size to 0 here so that changes to the host component's
        size will not be thwarted by this skin part's minimum size.   This is a compromise,
        more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
    -->
    <!--- @copy spark.components.SkinnableContainer#contentGroup -->
    <s:Group id="contentGroup" left="10" right="10" top="10" bottom="10" minWidth="0" minHeight="0">
        <s:layout>
            <s:BasicLayout>
            </s:BasicLayout>
        </s:layout>
    </s:Group>

</s:Skin>

在我的主要部分中,我将两个部分组件放入一个面板中的VGroup(这里是VGroup内容):

<component:GlassSectionComponent title="titi" width="100%" height="100%" skinClass="skin.GlassSectionContainerSkin">
                                        <s:HGroup left="7" right="3" top="10" bottom="5" width="100%" height="100%">
                                            <s:Button id="mybutn0" label="click!/>
                                            <s:Button id="mybutn1" label="click!/>
                                        </s:HGroup>
                                    </component:GlassSectionComponent>
<component:GlassSectionComponent title="toto" width="90%" height="90%" skinClass="skin.GlassSectionContainerSkin">
                                        <s:VGroup left="7" right="3" top="10" bottom="5" width="100%" height="100%">
                                            <s:Button id="mybutn2" label="click!/>
                                            <s:Button id="mybutn3" label="click!/>
                                        </s:VGroup>
                                    </component:GlassSectionComponent>

你可以看到在我的皮肤中我放了一个名为“fitContent”的函数,以便皮肤适合contentGroup的大小。但即使它适用于VGroup,当鼠标悬停在按钮上时,包含HGroup的部分也会逐步调整大小。我怀疑我的“fitContent”功能有问题,但我不确定。

1 个答案:

答案 0 :(得分:1)

每当将任何内容添加到容器(或其子项或孙子项)时,都会调用fitContent。有时当你设置minWidth和minHeight然后使用invalidateSize时,你可以进入一个环境,其中的东西会变得很大......我无法确定这种情况发生的确切位置。

这是一个想法:SkinnableContainer的默认大小足以适合孩子们。所以,看看BorderContainer并查看它覆盖的位置,然后重写它。或者,从SkinnableContainer开始。 Panel已经有一个标题栏,其默认大小足以适合其孩子。为什么不给它一个自定义皮肤,如果它显示标题的方式不完全是你想要的?