2
votes

I've created a skin that allows me to have two labels on a spark button, but the button text won't center vertically. It stays at the top of the button no matter what settings I give it. The icon in the skin DOES however, center vertically.

This is the skin:

<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
         minWidth="82" minHeight="82" 
         alpha.disabled="0.5" initialize="autoIconManagement=false">
<fx:Metadata>[HostComponent("com.XXXX.components.TwoLineButton")]</fx:Metadata>

<!-- states -->
<s:states>
    <s:State name="up" />
    <s:State name="over" />
    <s:State name="down" />
    <s:State name="disabled" />
</s:states>

<s:Image source="{getStyle('upSkin')}" 
         source.over="{getStyle('overSkin')}" 
         source.down="{getStyle('downSkin')}" 
         source.disabled="{getStyle('disabledSkin')}" 
         width="100%" height="100%"
         />

<s:HGroup verticalAlign="middle" height="100%" width="100%"
          paddingLeft="{getStyle('paddingLeft')}" 
          paddingRight="{getStyle('paddingRight')}" 
          paddingTop="{getStyle('paddingTop')}" 
          paddingBottom="{getStyle('paddingBottom')}"
          gap="{getStyle('horizontalGap')}" 
          verticalCenter="0">

    <s:BitmapImage id="iconDisplay" includeInLayout="{iconDisplay.source}"/>

    <s:VGroup gap="{getStyle('verticalGap')}" height="100%" width="100%">
        <s:Label id="labelDisplay"
                 textAlign="center"
                 width="100%"
                 maxDisplayedLines="1"
                 horizontalCenter="0" verticalCenter="1" verticalAlign="middle"
                 left="10" right="10" top="2" bottom="2">
        </s:Label>

        <s:Label id="bottomLabelDisplay"
                 textAlign="center"
                 width="100%"
                 maxDisplayedLines="1"
                 horizontalCenter="0" verticalCenter="1" verticalAlign="middle"
                 left="10" right="10" top="2" bottom="2">
        </s:Label>
    </s:VGroup>
</s:HGroup>

This is the code I'm calling it with:

<components:TwoLineButton
                width="308"
                label="TopLabel"
                bottomLabel="Bottom label"
                click="handleButtonClick(event)"
                />

I've tried making the HGroup use a hardcoded height value, and that doesn't work either.

Thanks in advance.

2

2 Answers

2
votes

You cannot use absolute constraints like 'x', 'y', 'left', 'right', 'top', 'bottom', 'horizontalCenter', 'verticalCenter', ... inside a relative layout like VerticalLayout (VGroup is just a Group with a VerticalLayout). This makes sense since you can't position something both relatively and absolutely. In this case the layout of the container takes precedence over whatever constraints you put on the child component. This means you can simply remove any of these constraints you have there: they simply don't have any effect.

Also 'verticalAlign' is a style you apply to a container, but it tells the container how to layout its children. You've assigned it to the Labels, so you're saying "lay out the text component inside the Label in the middle of the Label component" and not "layout the Label component in the middle of the VGroup". So this one is also redundant.

Something like the following should fix your issue:

<s:VGroup height="200">
    <s:Label text="A" height="50%" verticalAlign="middle" />
    <s:Label text="B" height="50%" verticalAlign="middle" />
</s:VGroup>

or if you want both Labels grouped together in the middle of the VGroup (it's not apparent from the description which one of both you want):

<s:VGroup height="200" verticalAlign="middle">
    <s:Label text="A" />
    <s:Label text="B" />
</s:VGroup>
1
votes

The HGroup in your skin should look something like this:

<s:HGroup verticalAlign="middle" height="100%" width="100%"
          paddingLeft="{getStyle('paddingLeft')}" 
          paddingRight="{getStyle('paddingRight')}" 
          paddingTop="{getStyle('paddingTop')}" 
          paddingBottom="{getStyle('paddingBottom')}"
          gap="{getStyle('horizontalGap')}" >

    <s:BitmapImage id="iconDisplay" includeInLayout="{iconDisplay.source}"/>

    <s:VGroup gap="{getStyle('verticalGap')}" width="100%" verticalAlign="middle" >
        <!-- not sure if you need 100% width here -->
        <s:Label id="labelDisplay"
                 textAlign="center"
                 width="100%"
                 maxDisplayedLines="1">
        </s:Label>

        <s:Label id="bottomLabelDisplay"
                 textAlign="center"
                 width="100%"
                 maxDisplayedLines="1">
        </s:Label>
    </s:VGroup>
</s:HGroup>

Your labels are in a VGroup so attributes like verticalCenter, horizontalCenter, top, left, etc. do not apply. These attributes only work in BasicLayout (absolutely positioned layouts).

I also removed the 100% height on the VGroup that contained the labels. This means that group of labels will only be as tall as necessary (so now we can actually center it).

Finally, added verticalAlign="middle" to the VGroup. Since the parent of this group is an HGroup, the VGroup should be positioned horizontally next to the BitmapImage if present, and vertically aligned in the middle.