гибкий пользовательский контейнер странное поведение автоматического изменения размера - PullRequest
0 голосов
/ 30 ноября 2011

Я закодировал компонент раздела (рамка + заголовок), который автоматически подгоняет размер содержимого (дочерних элементов).

Вот код компонента:

<?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», чтобы скин соответствовал размеру группы содержимого. Но даже если он отлично работает для VGroup, раздел, содержащий HGroup, изменяет размер шаг за шагом, когда моя мышь находится над кнопками. Я подозреваю проблему в моей функции «fitContent», но я не уверен.

1 Ответ

1 голос
/ 30 ноября 2011

Всякий раз, когда в контейнер добавляется что-либо (или его дочерние элементы, или внуки), вызывается ваш fitContent. Иногда, когда вы устанавливаете minWidth и minHeight, а затем invalidateSize, вы можете зацикливаться на том, что вещи меняются в размерах ... Я не смог определить точное место, где это происходит.

Вот идея: размер по умолчанию для SkinnableContainer достаточно велик, чтобы соответствовать детям. Итак, посмотрите на BorderContainer и посмотрите, где он переопределяет это, и переопределите его обратно. Или просто начните со SkinnableContainer. Панель уже имеет строку заголовка, и ее размер по умолчанию достаточно велик, чтобы соответствовать ее дочерним элементам. Почему бы просто не придать ему индивидуальный скин, если способ отображения заголовка не совсем то, что вам нужно?

...