如何在flex中实现Expander(单项手风琴)?

时间:2013-08-08 16:28:55

标签: flex flex4

我有一个 Flex 应用程序,其行为如下所述

How to improve this to an Accordion or similar Flex component

我想解决两件事

  1. 我想向用户说明可以显示更多信息。目前“Profundidad”只是一个标签。
  2. 下面显示的元素未与其上方的元素对齐,因为这实际上是状态更改时显示的另一个组件
  3. 我尝试过使用Accordion,但是当你有一个带有单个元素的Accordion时,该元素总是可见的,所以它不能折叠和展开

    我想要的是最终结果看起来尽可能接近这个

    enter image description here

2 个答案:

答案 0 :(得分:0)

您可以使用状态轻松实现此目的。首先定义两个状态:'normal'和'expanded'

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

然后使用includeInexcludeFrom根据需要显示组件:

<!-- always visible components -->
<s:Label text="FPBAF20F"/>
<s:Label text="N/A"/>

<s:Button label="Profundidad" 
          click="currentState = currentState == 'expanded' ? 'normal' : 'expanded'"/>

<!-- the compra/venta grid only shown in 'expanded' state -->
<s:DataGrid includeIn="expanded" />

点击处理程序不是很漂亮,但您明白了:当您单击按钮时,状态从“正常”切换为“展开”,然后再次单击时返回。
这就是它的全部内容。

如果您更喜欢开箱即用的解决方案,您可以自由使用我创建的CollapsiblePanel组件:https://github.com/RIAstar/CollapsiblePanelFx;)

答案 1 :(得分:0)

也许这段代码会很有用:

MXML文件

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:classes="com.classes.*">

    <classes:CollapsiblePanel id="cp" title="Profundidad (Click me)" open="false">
        <mx:DataGrid> 
            <mx:ArrayList>
                <fx:Object Cantidad="" Precio=""/>
            </mx:ArrayList>
        </mx:DataGrid>
    </classes:CollapsiblePanel>
</s:Application>

<强> CollapsiblePanel.as 即可。请注意,在我的情况下,此类位于com.classes包中,您可以根据需要将其放在该位置。

package com.classes {
import flash.events.*;
import mx.effects.AnimateProperty;
import mx.events.*;
import mx.containers.Panel;
import mx.core.ScrollPolicy;

[Style(name="closedIcon", property="closedIcon", type="Object")]
[Style(name="openIcon", property="openIcon", type="Object")]

public class CollapsiblePanel extends Panel {
        private var _creationComplete:Boolean = false;
        private var _open:Boolean = true;
        private var _openAnim:AnimateProperty;

        public function CollapsiblePanel(aOpen:Boolean = true):void
        {
            super();
            open = aOpen;
            this.addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
        }

        private function creationCompleteHandler(event:FlexEvent):void
        {
            this.horizontalScrollPolicy = ScrollPolicy.OFF;
            this.verticalScrollPolicy = ScrollPolicy.OFF;

            _openAnim = new AnimateProperty(this);
            _openAnim.duration = 300;
            _openAnim.property = "height";

            titleBar.addEventListener(MouseEvent.CLICK, headerClickHandler);

            _creationComplete = true;
        }

        private function headerClickHandler(event:MouseEvent):void { toggleOpen(); }

        private function callUpdateOpenOnCreationComplete(event:FlexEvent):void { updateOpen(); }

        private function updateOpen():void
        {
            if (!_open) height = closedHeight;
            else height = openHeight;
            setTitleIcon();
        }

        private function get openHeight():Number {
            return measuredHeight;
        }

        private function get closedHeight():Number {
            var hh:Number = getStyle("headerHeight");
            if (hh <= 0 || isNaN(hh)) hh = titleBar.height;
            return hh;
        }

        private function setTitleIcon():void
        {
            if (!_open) this.titleIcon = getStyle("closedIcon");
            else this.titleIcon = getStyle("openIcon");
        }

        public function toggleOpen():void
        {
            if (_creationComplete && !_openAnim.isPlaying) {

                _openAnim.fromValue = _openAnim.target.height;
                if (!_open) {
                    _openAnim.toValue = openHeight;
                    _open = true;
                    dispatchEvent(new Event(Event.OPEN));
                }else{
                    _openAnim.toValue = _openAnim.target.closedHeight;
                    _open = false;
                    dispatchEvent(new Event(Event.CLOSE));
                }
                setTitleIcon();
                _openAnim.play();
            }
        }

        public function get open():Boolean {
            return _open;
        }

        public function set open(aValue:Boolean):void {
            _open = aValue;
            if (_creationComplete) updateOpen();
            else this.addEventListener(FlexEvent.CREATION_COMPLETE, callUpdateOpenOnCreationComplete, false, 0, true);
            }

        override public function invalidateSize():void {
            super.invalidateSize();
            if (_creationComplete)
                if (_open && !_openAnim.isPlaying) this.height = openHeight;
            }
    }
}

Yon可以看到此SWF在行动 here

可折叠面板 的源代码为 here 。 我希望这会对你有所帮助。