Как нарисовать объединенную границу вокруг двух компонентов? - PullRequest
2 голосов
/ 17 марта 2011

Прежде чем заняться этим самостоятельно, я подумал, что выбрал умы сообщества SO.

Давайте предположим, что у меня есть Image, который использовал кнопку.По умолчанию изображение не имеет рамки вокруг него.Нажатие на это Image приведет к отображению другого компонента под ним или рядом с ним.Когда отображается второй компонент, я хочу нарисовать объединенную границу вокруг Image и второго компонента.

Второй компонент не будет отображаться по умолчанию.Он будет виден только после нажатия на Image с помощью popupManager, PopUpAnchor, установки свойства visible и т. Д.

Пример перед нажатием:

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

Пример после нажатия:

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

Насколько сложно будет создать что-то подобное?

Ответы [ 2 ]

3 голосов
/ 11 апреля 2011

Если вы используете 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);
    }
}

MyDetailsSkin.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);
    }
}

я очень надеюсь, что это поможет

0 голосов
/ 17 марта 2011

Уверен, что вы можете сделать это со стилями
Добавьте третий контейнер, который я пометил ****
отключите верхнюю и правую границы на моем новом контейнере (
***)
отключите нижнюю границу вашего контейнера изображений
отключите верхнюю границу вашего второго компонента

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