Flex / Accordion: условно скрыть ребенка - PullRequest
2 голосов
/ 04 января 2009

Как мне спрятать ребенка в гармошке? Кажется, использование visible не работает, и я не за ним.

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

Ответы [ 11 ]

7 голосов
/ 04 января 2009

Я думаю, ты не можешь это скрыть. Странно, что свойство visible не работает ... Во всяком случае, я бы контролировал детей с помощью кода, удалял и вставлял их по мере необходимости в приложении. Скрытие:

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

Возможно, вы захотите сохранить ссылку на "скрытого" потомка, чтобы вы могли добавить его позже.

1 голос
/ 10 мая 2011

Вы можете переопределить логику 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);
    }
}
}
1 голос
/ 01 октября 2010

Извините, я не согласен с удалением дочернего элемента, потому что у вас возникнут проблемы при добавлении его обратно на место в точном порядке.

Пример: если у вас есть 5 страниц в аккордеоне, вы удаляете ребенка 1 и 3, теперь при любом условии вы хотите, чтобы номер 3 вернулся в аккордеон, как вы кладете его обратно? потому что индекс больше не равен 3 (помните, что 1 тоже удален).

Я нашел хорошее решение здесь . Короче говоря, вы делаете свой собственный аккордеон с помощью enalbe и отключаете возможность, когда включаете и отключаете определение для дочернего контейнера.

здесь я вставляю код аккордеона:

/**
 * 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;
        }
    }
}

Возможно, мой ответ уже не актуален для вас, но я надеюсь, что он может помочь кому-то еще, кто сталкивается с той же проблемой.

1 голос
/ 07 декабря 2009

Вы также можете создать потомок аккордеона с помощью таких методов, как 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;
    }
    }
1 голос
/ 06 января 2009

Это не ответ, просто некоторые любопытные вещи, которые я обнаружил, пытаясь найти другое решение этой проблемы:

Заголовки Accordion имеют свойство visible и метод setActualSize. Последний принимает высоту и ширину и устанавливает каждый в ноль ...

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

... выполняет то же самое, что и установка visible = false, то есть скрывает содержимое заголовка, но не удаляет его область из аккордеона. Я надеялся обмануть аккордеона, чтобы скрыть ребенка, но не такая удача ... тем не менее, это может быть путь для продолжения попыток. Если у меня будет больше времени, я продолжу исследовать, но сейчас у меня не хватает полосы пропускания ...

0 голосов
/ 18 августа 2012

Вот решение, как свернуть гармошку по щелчку заголовка.

<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>
0 голосов
/ 25 января 2011

Вот мое решение:

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

Я скопировал и изменил код Аккордеона, поэтому, если у ребенка есть свойство includeInLayout, равное false, оно не будет отображаться.

0 голосов
/ 04 марта 2010

Попробуйте это

accrod.getHeaderAt(0).enabled=false;
accrod.getHeaderAt(0).visible=false;
0 голосов
/ 16 декабря 2009

<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>

0 голосов
/ 07 января 2009

Аккордеонный контроль всегда имеет 1 открытого ребенка. Открыв другого потомка, текущий закроется.

Если вы хотите, чтобы более одного дочернего элемента было открыто одновременно или все дочерние элементы были закрыты, вы можете использовать компонент VStack, доступный по адресу: http://weblogs.macromedia.com/pent/archives/2007/04/the_stack_compo.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...