如何围绕两个组件绘制连接边框?

时间:2011-03-16 23:19:36

标签: flex actionscript-3 flex4 border

在我自己解决这个问题之前,我认为我选择了SO社区的思想。

我们假设我有一个Image使用了一个按钮。默认情况下,图像周围没有边框。单击此Image将导致其下方或旁边显示另一个组件。当显示第二个组件时,我想在Image和第二个组件周围绘制一个连接边框。

默认情况下,第二个组件不可见。只有使用ImagepopupManager,设置PopUpAnchor属性等点击visible后才能看到它。

点击前的示例:

+--------------------------------+
|                                |
|   XXX  <-- My Image            |
|   XXX                          |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
+--------------------------------+

点击后的示例:

+--------------------------------+
|  +---+                         |
|  |XXX|  <-- My Image           |
|  |XXX|_______________          |
|  |                   |         |
|  |   My Second       |         |
|  |   Component       |         |
|  |                   |         |
|  |                   |         |
|  +-------------------+         |
|                                |
+--------------------------------+

创造这样的东西有多难?

2 个答案:

答案 0 :(得分:3)

如果您使用的是flex4 / spark,那么您应该考虑换肤(无论如何,borderSides样式仅在Halo中可用)。

这是一个小样本,用于实现图像中显示的行为:

collapsed state expanded state

它使用具有两种状态的自定义组件(折叠和展开)。
文本仅附加在展开状态,边框皮肤也是如此。
为此,您需要两个皮肤类,这些皮肤类将应用于图像和文本组件的父级。

应用

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:my="*">
    <s:VGroup width="100%" height="100%" paddingLeft="20" paddingTop="20">
        <my:ExpandableImage id="component" width="300" />
        <s:Button label="{component.currentState}" click="component.changeState(event);" />
    </s:VGroup>
</s:WindowedApplication>

ExpandableImage.mxml //具有两种状态的自定义组件

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    verticalScrollPolicy="off" horizontalScrollPolicy="off"
    verticalGap="0" width="100%"
    currentState="collapsedState">
    <fx:Script>
        <![CDATA[

            public function changeState(event:MouseEvent):void
            {
                if (currentState == 'collapsedState')
                    currentState = 'expandedState';
                else
                    currentState = 'collapsedState';
            }

        ]]>
    </fx:Script>
    <mx:VBox id="imgHolder" borderSkin="MyImageSkin" 
        width="50" height="50" includeIn="collapsedState, expandedState" cornerRadius="5"
        backgroundAlpha="1" borderAlpha="0" backgroundColor="#FFFFFF" borderColor="#000000">
        <mx:Image id="img" source="{IMyConstants.MYLOGO}" 
            width="48" height="48"
            mouseEnabled="true" click="changeState(event)" />
    </mx:VBox>
    <mx:VBox id="txtHolder" borderSkin="MyDetailsSkin" 
        width="100%" height="100%" includeIn="expandedState" cornerRadius="5"
        backgroundAlpha="1" borderAlpha=".5" backgroundColor="#FFFFFF" borderColor="#000000">
        <mx:Text id="txt" text="{IMyConstants.LOREMIPSUM}" 
            width="100%" />
    </mx:VBox>
    <mx:states>
        <s:State name="collapsedState" />
        <s:State name="expandedState" />
    </mx:states>
    <mx:transitions>
        <mx:Transition fromState="collapsedState" toState="expandedState">
            <s:Parallel duration="500">
                <mx:Resize target="{this}" />
                <mx:SetStyleAction target="{imgHolder}" 
                    name="borderAlpha" value=".5" />
            </s:Parallel>
        </mx:Transition>
        <mx:Transition fromState="expandedState" toState="collapsedState">
            <s:Parallel duration="500">
                <mx:Resize target="{this}" />
                <mx:SetStyleAction target="{imgHolder}" 
                    name="borderAlpha" value="0" />
            </s:Parallel>
        </mx:Transition>
    </mx:transitions>
</mx:VBox>

MyImageSkin.as //要应用于图像组件父级的皮肤

public class MyImageSkin extends RectangularBorder 
{
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
        var cornerRadius:Number = getStyle("cornerRadius");
        var borderColor:int = getStyle("borderColor");
        var borderAlpha:Number = getStyle("borderAlpha");
        var backgroundColor:int = getStyle("backgroundColor");
        var backgroundAlpha:Number = getStyle("backgroundAlpha");
        graphics.clear();
        //border
        drawRoundRect(0, 0, unscaledWidth, unscaledHeight, 
            {tl: cornerRadius, tr:cornerRadius, bl: 0, br: 0}, 
            borderColor, borderAlpha);
        //content
        drawRoundRect(1, 1, unscaledWidth-2, unscaledHeight-1, 
            {tl: cornerRadius, tr:cornerRadius, bl: 0, br: 0}, 
            backgroundColor, backgroundAlpha);
    }
}

MyDetailsS​​kin.as //要在文字的父级上应用的皮肤

public class MyDetailsSkin extends RectangularBorder 
{
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void 
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
        var cornerRadius:Number = getStyle("cornerRadius");
        var borderColor:int = getStyle("borderColor");
        var borderAlpha:Number = getStyle("borderAlpha");
        var backgroundColor:int = getStyle("backgroundColor");
        var backgroundAlpha:Number = getStyle("backgroundAlpha");
        graphics.clear();
        //border
        drawRoundRect(0, 0, unscaledWidth, unscaledHeight, 
            {tl: 0, tr:cornerRadius, bl: cornerRadius, br: cornerRadius}, 
            borderColor, borderAlpha);
        //content
        drawRoundRect(1, 1, unscaledWidth-2, unscaledHeight-2, 
            {tl: 0, tr:cornerRadius, bl: cornerRadius, br: cornerRadius}, 
            backgroundColor, backgroundAlpha);
        //clear separator
        drawRoundRect(1, 0, 49, 1, {tl: 0, tr:1, bl: 1, br: 1}, backgroundColor, 1);
    }
}

我真的希望这会有所帮助

答案 1 :(得分:0)

非常确定你可以用款式来做到这一点 添加第三个标有 ****
的容器 在我的新容器上关闭顶部和右侧边框(
***)
关闭图像容器上的底部边框 关闭第二个组件上的顶部边框

+--------------------------------+
|  +---+****************         |
|  |XXX|  <-- My Image *         |
|  |XXX|_______________*         |
|  |                   |         |
|  |   My Second       |         |
|  |   Component       |         |
|  |                   |         |
|  |                   |         |
|  +-------------------+         |
|                                |
+--------------------------------+