Flex / Accordion:有条件地隐藏孩子

时间:2009-01-04 11:12:29

标签: flex actionscript-3

如何用手风琴隐藏孩子?使用可见似乎不起作用,启用不是我想要的。

<mx:Accordion>
<mx:VBox width="100%" height="100%" label="Foo" id="viewOverview" visible="false">
...
</mx:VBox>
...
</mx:Accordion>

11 个答案:

答案 0 :(得分:7)

我认为你无法隐藏它。奇怪的是,可见属性不起作用......无论如何,我会通过代码控制孩子,并根据应用的需要删除和插入它们。隐藏:

function hideFoo():void {
    this.theAccordion.removeChild(this.vboxFoo);
}

您可能希望保留对“隐藏”子项的引用,以便稍后再添加它。

答案 1 :(得分:1)

这不是一个答案,只是在尝试找到解决此问题的另一个解决方案时发现的一些奇怪的事情:

Accordion标头具有visible属性和setActualSize方法。后者采用高度和宽度,并将每个设置为零...

acc.getHeaderAt(0).setActualSize(0,0);

...完成与设置visible = false相同的事情,即它隐藏了标题的内容,但是没有从手风琴中删除它的区域。我希望能够欺骗手风琴以隐藏孩子,但没有这样的运气......尽管如此,这可能是继续尝试的途径。如果我有更多的时间,我将继续探索,但我现在已经没有带宽......

答案 2 :(得分:1)

您还可以使用showHeader,hideHeader,isHeaderHidden等方法创建手风琴的后代,其中包含哈希表以跟踪隐藏的元素,类似于下面的元素:

public class AccordionHideHeader extends Accordion
    {
        private var _hiddenHeader:Dictionary=new Dictionary();

        public function AccordionHideHeader()
        {
            super();
        }

        public function hideHeader(header:DisplayObject):void
        {
            if (contains(header))
            {
                _hiddenHeader[header]=getChildIndex(header);
                removeChild(header);
            }


        }

        public function showHeader(header:DisplayObject):void
        {
            if (!contains(header))
            {
                addChildAt(header, _hiddenHeader[header]);
                delete _hiddenHeader[header]
            }
        }

        public function isHeaderHidden(header:DisplayObject):Boolean
    {                       
        for (var key:Object in _hiddenHeader)
        {
            if (key==header)
                return true;                
        }

        return false;
    }
    }

答案 3 :(得分:1)

抱歉,我不同意删除孩子,因为在按照确切的顺序将其添加回其位置时会遇到问题。

示例:如果手风琴有5页,你可以删除1号和3号小孩,现在在任何情况下,你想要3号回到手风琴,你怎么把它放回去?因为索引不再是3(rember,1也被删除)。

我找到了一个很好的解决方案here。简而言之,您可以使用enalbe创建自己的acordion并禁用在子容器上启用和禁用define的功能。

这里我粘贴了旋转码:

/**
 * http://blog.flexexamples.com/2008/05/30/preventing-users-from-clicking-on-an-accordion-containers-header-in-flex/
 */
package comps {
    import mx.containers.accordionClasses.AccordionHeader;
    import mx.events.FlexEvent;

    public class MyAccHeader extends AccordionHeader {
        public function MyAccHeader() {
            super();
            addEventListener(FlexEvent.INITIALIZE, accordionHeader_initialize);
        }

        private function accordionHeader_initialize(evt:FlexEvent):void {
            enabled = data.enabled;
        }
    }
}

也许我的回答对您来说不再相关,但我希望可以帮助其他遇到同样问题的人。

答案 4 :(得分:1)

您可以覆盖Accordion逻辑和用户includeInLayout属性来控制子项的可见性。

如果您将所有孩子都设置为MXML,这将有效。

import flash.events.Event;

import mx.containers.Accordion;
import mx.core.UIComponent;

public class DynamicAccordion extends Accordion
{
public function DynamicAccordion()
{
}

private var allChildern:Array;

override protected function childrenCreated():void
{
    allChildern = new Array();
    for (var i:int = numChildren - 1; i >= 0 ; i--)
    {
        var child:UIComponent = getChildAt(i) as UIComponent;
        if (child)
        {
            child.addEventListener("includeInLayoutChanged",  childIncludeLayoutChangedHandler);
            if (!child.includeInLayout)
            {
                removeChild(child);
            }
            allChildern.push(child);
        }
    }
    allChildern = allChildern.reverse();

    super.childrenCreated();
}

private function childIncludeLayoutChangedHandler(event:Event):void
{
    var child:UIComponent = event.currentTarget as UIComponent;
    if (child.includeInLayout)
    {
        var index:int = allChildern.indexOf(child);
        addChildAt(child, index);
    }
    else
    {
        removeChild(child);
    }
}
}

答案 5 :(得分:0)

我认为您可能必须实际删除手风琴儿童本身(例如使用State removeChild()机制)。如果您需要保留对象本身,只需在全局变量中保留对它的引用。

干杯

答案 6 :(得分:0)

手风琴控制总是打开一个孩子。通过打开另一个孩子,当前的孩子将关闭。

如果您希望一次打开一个以上的孩子或关闭所有孩子,您可以使用以下网址提供的VStack组件:http://weblogs.macromedia.com/pent/archives/2007/04/the_stack_compo.html

答案 7 :(得分:0)

<mx:Script>
    <![CDATA[


        private function hideFn():void
        {
            acc.removeChildAt(0);                   
        }

        private function showFn():void
        {
            acc.addChildAt(helloBox  , 0);              
        } 

    ]]>
</mx:Script>
<mx:VBox>
<mx:Accordion id="acc" width="200" height="200">    

    <mx:VBox id="helloBox" label="Test">

        <mx:Label text="hello"/>

    </mx:VBox>

    <mx:VBox label="Test2">

        <mx:Label text="hello again"/>

    </mx:VBox>

</mx:Accordion>

<mx:Button label="hide" click="hideFn()"/>
<mx:Button label="show" click="showFn()"/>
</mx:VBox>

答案 8 :(得分:0)

试试这个

accrod.getHeaderAt(0).enabled=false;
accrod.getHeaderAt(0).visible=false;

答案 9 :(得分:0)

这是我的解决方案:

http://weflex.wordpress.com/2011/01/25/flex-accordion-hideshow-headers/

我复制并修改了Accordion的代码,因此如果孩子的“includeInLayout”属性为false,则不会显示。

答案 10 :(得分:-1)

以下是解决方案,如何在点击标题时折叠手风琴。

<mx:Script>
    <![CDATA[
        import mx.events.IndexChangedEvent;

        private var isAccordionClosed:Boolean;

        private function myAccordion_clickHandler(event:MouseEvent):void
        {
            trace(event.currentTarget.label);
            var selIdx:int = myAccordion.selectedIndex;

            isAccordionClosed = (isAccordionClosed) ? false : true; 
            if (isAccordionClosed)
            {
                collapseAccordion(selIdx, !isAccordionClosed);
            }
            else
            {
                collapseAccordion(selIdx, !isAccordionClosed);
            }
        }

        private function collapseAccordion(idx:int, showHide:Boolean):void
        {
            switch(idx)
            {
                case 0:
                    vb1.scaleX = vb1.scaleY = int(showHide); 
                    break;

                case 1:
                    vb2.scaleX = vb2.scaleY = int(showHide);
                    break;

                case 2:
                    vb3.scaleX = vb3.scaleY = int(showHide);
                    break;

                case 3:
                    vb4.scaleX = vb4.scaleY = int(showHide); 
                    break;

                case 4:
                    vb5.scaleX = vb5.scaleY = int(showHide);
                    break;
            }
        }


        private function myAccordion_changeHandler(event:IndexChangedEvent):void
        {
            isAccordionClosed = true;
        }

    ]]>
</mx:Script>

<mx:Accordion id="myAccordion" x="200" y="200" click="myAccordion_clickHandler(event)" resizeToContent="true" 
              width="399" verticalGap="0" change="myAccordion_changeHandler(event)">
    <mx:VBox id="vb1" label="Chapter 1">
        <mx:Label text="Accordion 1"  width="397" textAlign="center" height="38"/>
    </mx:VBox>

    <mx:VBox id="vb2" label="Chapter 2">
        <mx:Label text="Accordion 2" width="397" textAlign="center" height="43"/>
    </mx:VBox>

    <mx:VBox id="vb3" label="Chapter 3">
        <mx:Label text="Accordion 3" width="397" textAlign="center" height="43"/>
    </mx:VBox>

    <mx:VBox id="vb4" label="Chapter 4">
        <mx:Label text="Accordion 4" width="397" textAlign="center" height="43"/>
    </mx:VBox>

    <mx:VBox id="vb5" label="Chapter 5">
        <mx:Label text="Accordion 5" width="397" textAlign="center" height="43"/>
    </mx:VBox>
</mx:Accordion>