How do I get my flex spark skin to center vertically? - apache-flex

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.

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>

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.

Related

Flex 4 - There is no scrollbar on Spark DataGrid

I have to display a lot of controls in my application. And I have done it using Group .
<s:Group clipAndEnableScrolling="true" >
<s:Scroller horizontalScrollPolicy="auto" verticalScrollPolicy="auto" top="0" bottom="0" right="0" left="0">
<s:Group clipAndEnableScrolling="true" >
<s:layout>
<s:VerticalLayout paddingTop="30" paddingLeft="20" paddingRight="20"/>
</s:layout>
<s:HGroup horizontalAlign="left" verticalAlign="top">
<s:Button id="clearButton" label="Clear"/>
<s:Button id="addEmployee" label="Add"/>
</s:HGroup>
<s:HGroup horizontalAlign="left" verticalAlign="top">
<s:Label id="mainLabel" text="Employee Details"/>
</s:HGroup>
<s:HGroup horizontalAlign="left" verticalAlign="top">
// some more components
</s:HGroup>
<s:HGroup horizontalAlign="left" verticalAlign="top">
<s:DataGrid id="grid">
// Grid column
</s:DataGrid>
</s:HGroup>
<s:HGroup horizontalAlign="left" verticalAlign="top">
<s:DataGrid id="dataGrid">
// Grid column
</s:DataGrid>
</s:HGroup>
</s:Group>
</s:Scroller>
</s:Group>
For this code, there is no scrollbar for both Grop and DataGrid. I don't have any idea about this scroller. How to add scrollbar in it? or How can I arrange my components?
First, you have to set height and width property for the Group container scroller. Than you have to set
verticalScrollPolicy="on" horizontalScrollPolicy="on"
for both DataGrid
And here, there is no need of Group before the scroller.
It seems like your group doesn't have a width or height set, but instead the top, right, bottom and left. I'd assume its not triggering the scroller to be necessary based on the contents.
Restrict the dimensions of the scroller component (width and height) and make sure the group's contents are larger than the scroller.
also, you can specify "viewport" on the scroller and pass in the id of the group inside.
the default value for viewport is null.
reference: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/components/Scroller.html
-AJ

Flex 4 scroller with group. Scrollbars not showing up

I know I have done this before but every time I work with scrollers and group it doesn't work for me and kills my 2 days.
<s:Scroller width="100%" height="100%" horizontalScrollPolicy="auto" verticalScrollPolicy="auto">
<s:Group clipAndEnableScrolling="true">...... ..... </s:Group></s:Scroller>
This is what I have. I have components inside my group with is more than enough to bring scrollers even on a big monitor. But I am not getting any scrollbars.
Kindly tell me what is that I am doing wrong here. because everytime I fix it and I struggle for the next time.
Thanks.
Try with this
Your scroller parent container need to set non-percentage height/width.
<s:BorderContainer width="120" height="100" backgroundColor="#FFFFFF">
<s:Scroller width="100%" height="100%">
<s:Group>
<s:layout>
<s:VerticalLayout horizontalAlign="justify"
clipAndEnableScrolling="true" />
</s:layout>
<s:Button label="button (1)" />
<s:Button label="button (2)" />
<s:Button label="button (3)" />
<s:Button label="button (4)" />
<s:Button label="button (5)" />
<s:Button label="button (6)" />
</s:Group>
</s:Scroller>
</s:BorderContainer>
Thank you for all your responses. After setting the minHeight it now works. I am able to achieve the scrollbars as expected (make it look like browser's scroll bar). Below is the code snippet
<s:Scroller width="100%" maxHeight="{this.height}">
<s:VGroup width="100%" minHeight="1000" height="100%" paddingLeft="40" paddingRight="40" paddingTop="0" >
..</s:VGroup></s:Scroller>
Kindly let me know if there is a better approach.
The Same code given by "Raja Jaganathan" itself will work with small modification on scroll parent height and width
Capabilities.screenResolutionX, Capabilities.screenResolutionY will give you the browser width and height respectively.

BorderContainer with text is not showing buttonMode correctly

In my code, I have a list made up of items from a dataprovider. The itemRenderer for the list consists of a BorderContainer with text in it. I'm mimicking a row of buttons on a scrolling list. I'd like the cursor to change to the hand cursor as it passes over the "button", but the pointer only changes in the part of the BorderContainer that isn't covered by the text.
I've set the buttonMode to true for the list, the BorderContainer, and the text, so why isn't the cursor changing when passing over the text?
This is the list code
<s:List id="listProject" width="100%" height="100%" horizontalScrollPolicy="off" allowMultipleSelection="false"
click="listProject_clickHandler(event)" itemRenderer="ProjectRenderer"
dataProvider="{listProjects}" creationComplete="listProject_creationCompleteHandler(event)" buttonMode="true">
And this is the renderer
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<!--<s:Label text="{data.header}"/>-->
<s:states>
<s:State name="normal"/>
<s:State name="hovered"/>
<s:State name="selected"/>
</s:states>
<!--<s:Image source.normal="{data.image1}" source.hovered="{data.image2}"/>-->
<s:BorderContainer width="200" height="50" backgroundColor="{data.color}"
borderColor.selected="#FFFFFF" borderVisible.normal="false"
borderVisible.selected="true" borderWeight.selected="4" borderStyle.selected="inset" buttonMode="true">
<s:layout>
<s:HorizontalLayout verticalAlign="middle" horizontalAlign="center"/>
</s:layout>
<mx:Text width="200" text="{data.header}" selectable="false"
color="#FFFFFF" fontSize="15" fontWeight="bold" leading="0" textAlign="center" buttonMode="true" useHandCursor="true"/>
</s:BorderContainer>
</s:ItemRenderer>
Just use a Spark Label instead of mx:Text and you'll be fine.
Also, there's some redundancy in your code. I took the liberty of trimming it down a little:
<s:BorderContainer width="200" height="50" backgroundColor="{data.color}"
borderColor.selected="#FFFFFF" borderVisible.normal="false"
borderVisible.selected="true" borderWeight.selected="4"
borderStyle.selected="inset" buttonMode="true">
<s:Label text="{data.label}" color="#FFFFFF" fontSize="15" fontWeight="bold"
horizontalCenter="0" verticalCenter="0"/>
</s:BorderContainer>
This will also fix that nasty jumpiness of the text when hovered or selected.
As soon as you do not need interaction with mx:Text, you can set mouseChildren property of its parent to false. It will fix the problem. Here is a short example:
<s:ItemRenderer>
<s:BorderContainer width="200" buttonMode="true" useHandCursor="true" mouseChildren="false">
<mx:Text text="No many text" selectable="false" />
</s:BorderContainer>
</s:ItemRenderer>

Adding two icons on left and right on spark button

I want to add two icons on spark button.I am using button skin.
But the icons are not coming properly. Do anyone is having any idea?
The code is:
<s:HGroup width="100%">
<s:HGroup id="iconContainer" top="1" bottom="1" left="0" right="0"
horizontalAlign="{iconPosition}" verticalAlign="middle">
<mx:Image id="iconImage" source="{icon}" />
</s:HGroup>
<s:HGroup id="decoratorContainer"
width="100%">
<s:Label id="labelDisplay"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="1"
horizontalCenter="0" verticalCenter="1"
left="0" right="0" top="2" bottom="2">
</s:Label>
<mx:Image id="image" source="{decorator}" />
</s:HGroup>
</s:HGroup>
Give absolute width and height to 'iconImage' and 'image' OR override commitProperties by calling invalidateProperties once the image size is known by the works of {Binding}. Hope it helped.

Flex Spark: How to right align an icon on a button or tabbar button?

I would like to right align an icon on a button or tabbarbutton and keep the text left aligned in Flex 4.0 Spark.
So far, I've come up with something like the following in my custom skin:
<s:HGroup>
<s:HGroup horizontalAlign="left">
<s:Label id="labelDisplay"
textAlign="left"
maxDisplayedLines="1"
top="10">
</s:Label>
</s:HGroup>
<s:HGroup horizontalAlign="right" bottom="5" right="0">
<s:BitmapImage source="#Embed('assets/images/icons/close.png')" />
</s:HGroup>
</s:HGroup>
But it seems silly to have an HGroup with 2 HGroup children just to get the horizontalAlign to the right.
Anyone know of a better way?
Thx,
=Dave
You could set the width of the label to be 100%.
<s:HGroup>
<s:Label id="labelDisplay" width="100%"/>
<s:BitmapImage source="#Embed('assets/images/icons/close.png')" />
</s:HGroup>
If your buttons are all an explicit width, you could also try something like this:
<s:HGroup>
<s:Label id="labelDisplay"/>
<mx:Spacer width="100%"/>
<s:BitmapImage source="#Embed('assets/images/icons/close.png')" />
</s:HGroup>

Resources