2011-11-30 49 views
0

我編寫了一個自動適合內容(兒童)大小的節組件(邊框+標題)。flex自定義容器奇怪的自動調整行爲

下面是部分代碼:

<?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」,使功能S親適合contentGroup的大小。但是,即使它適用於VGroup,當鼠標懸停在按鈕上時,包含HGroup的部分也會逐步調整大小。我懷疑我的「fitContent」功能存在問題,但我不確定。

回答

1

每當有任何東西被添加到容器(或其子女或孫輩)時,您的fitContent將被調用。有時,當你設置minWidth和minHeight,然後invalidateSize,你可以進入一個循環,其中的東西蠕變的大小...我一直無法確定這發生的確切位置。

這是一個想法:SkinnableContainer的默認大小足夠大以適合兒童。所以,看一下BorderContainer,看看它覆蓋的地方,並覆蓋它。或者,從SkinnableContainer開始。面板已經有一個標題欄,並且其默認大小足以適合其子級。爲什麼不給它一個自定義皮膚,如果它顯示標題的方式並不完全是你想要的?

+0

我glassSectionComponent已經是一個SkinnableContainer,如果你看我的代碼,我用了一個皮膚...此外,該SkinnableContainer不夠大,以適應孩子們,這就是爲什麼我所編碼的fitContent功能。我想要一個在添加子項時調整自身大小的組件。 VGroup的行爲完全正確。我只是想知道爲什麼它不適用於HGroup。 – TheFrenchGuy

+0

而不是繞過組件無效週期,嘗試擺脫你有什麼,並把它放在覆蓋測量()。你需要去掉對invalidateSize()和invalidateDisplayList()的調用。當發生任何影響組件大小的任何事情時,Measure()都會被調用。 –

+0

我重寫了測量方法,它像一個魅力一樣工作!非常感謝! – TheFrenchGuy