I usually set the layout like this
<s:Group>
<s:layout>
<s:VerticalLayout gap="10"/>
</s:layout>
</s:Group>
but not sure how to specify the gap if I want to use new VerticalLayout
The VerticalLayout constructor does not have any parameters, so you won't be able to do this in-line in MXML as part of the layout property. You'll have to set the gap property on the layout after creating it. Perhaps in a creationComplete handler, do something like this:
groupID.layout.gap = 10;
You can probably even do this in-line:
<s:Group layout="{new VerticalLayout()}" id="groupID" creationComplete="{groupID.layout.gap = 10}"></s:Group>
Related
Is there any way to use Flex CSS to set the padding on this BorderContainer?
<s:BorderContainer width="100%" height="100%">
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Label text="asdfasdf" />
</s:BorderContainer>
I'm trying to avoid adding an extra unnecessary VGroup. Setting the padding with CSS has no effect. (I'm guessing since paddingLeft isn't a defined style on BorderContainer.)
s|BorderContainer {
paddingLeft: 10;
}
Is there any way to modify properties of the layout with CSS? I don't want to have to hard code padding in a ton of places.
You can add a custom style to the skin of your BorderContainer. Something like this:
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
var paddingLeft:* = getStyle('paddingLeft');
elementToPad.left = paddingLeft;
//or
layoutToPad.paddingLeft = paddingLeft;
//or
elementToPad.setStyle('paddingLeft', paddingLeft);
//depending on what kind of element you wish to pad
}
That way you can have different paddings applied through CSS, using a single Skin class and you can avoid code duplication.
Only downside is: you won't get IDE support because the host component won't know about the style you added; and the compiler will throw an error if you try to set the style in MXML, but that's what you were trying to avoid in the first place.
Define a custom syle whcih specifies the paddings.
.myCustomStyle { paddingLeft: 10;}
In the code, get this style value using styleManager and set it for the vertical layout
<s:layout>
<s:VerticalLayout paddingLeft= "value got from the style manager"/>
</s:layout>
I have a Vgroup with some components aligned par with its layout properties(vertical). I need to add one more component at an absolute X,Y position, overriding the alignment. I tried includeinlayout=false, but the component turns invisible then. Is it possible in flex?
No, this is not possible. A VGroup will ignore properties such as X, and Y. IF the component is visible, then includeInLayout is also ignored.
You'll have to layout your extra component outside of the VGroup, or switch to a Group and layout everything absolutely.
It is not possible! But you always can get global coordinates of the needed DisplayObject and show some PopUps or other components near to this target.
MXML:
<s:VGroup x="50" y="50">
<s:Button width="250" height="250" id="b1"/>
<s:Button width="250" height="250" id="b2"/>
</s:VGroup>
<s:Button id="addon"/>
AS:
var rect:Rectangle = b2.getBounds(this);
addon.x = rect.x + rect.width - addon.width;
addon.y = rect.y;
I need some code to run in a component after all the sizes of its children are known. The component has an absolute layout. I thought my component's measure() function would get called after all it's children's measure() functions had been called, but it seems like since it has an absolute layout, it never even calls measure.
Anyways, it's a Canvas and my override protected function measure():void never runs. What am I doing wrong?
updateDisplayList() is called in UIComponent's commitProperties. I believe this is called after the child sizes are known, and it is where you are supposed to put your layout code.
measure() is not called when you explicitly set a width and height on your components. If you have an absolute layout on your Canvas, but do not set a width and height, measure() will be called.
HTH;
Amy
You don't need to override anything, simply add a listener to the creationComplete of your component. This event is "Dispatched when the component has finished its construction, property processing, measuring, layout, and drawing."
Example where the component inherits from s:Group
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"
creationComplete="group1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function group1_creationCompleteHandler(event:FlexEvent):void
{
//TODO add code here
}
]]>
</fx:Script>
</s:Group>
How do I get corner radius on my TextInput component in Flex 4.
<s:TextInput prompt="username" width="150" maxChars="100" id="txt_username"
color="#000000"/>
Create a custom skin (possibly by copying spark TextInputSkin) and add a border graphic with rounded corners, like this:
<!-- border -->
<s:Rect id="border" left="0" right="0" top="0" bottom="0"
radiusX="10" radiusY="10">
<s:stroke>
<s:SolidColorStroke id="borderStroke" weight="1" />
</s:stroke>
</s:Rect>
If you want more special rounded corners you can also use these attributes:
topLeftRadiusX="4" topLeftRadiusY="8"
bottomLeftRadiusX="2" bottomRightRadiusY="10"
The default TextInputSkin does not allow for rounded corners, so there is no style that you could set on your TextInput to do it. So, no, there's no other way than creating a custom skin class.
You could take it a step further and make it dynamic. Create a custom TextInputSkin based on spark TextInputSkin and in the updateDisplayList method add this code above the super.updateDisplayList() call.
In YourTextInputSkin.mxml,
// in updateDisplayList()
if (getStyle("cornerRadius")!==undefined) {
border.radiusX = border.radiusY = getStyle("cornerRadius");
background.radiusX = background.radiusY = getStyle("cornerRadius");
}
That's it. You're done!
Now to use it add a CSS class selector to add a cornerRadius style like so:
/* set the Textinput.styleName to this style */
s|TextInput.roundedInput
{
contentBackgroundAlpha: .4;
contentBackgroundColor: #000000;
cornerRadius: 10;
skinClass: ClassReference("view.skins.TextInputRoundedSkin");
}
And set your instance to the class,
<s:TextInput styleName="roundedInput"/>
Unfortunately, you can't set the cornerRadius style on TextInput component instance in MXML. Should Flex support a styles tag for this type of thing like HTML tags do? Should styles declared in the Skin be proxied to the component using them? Currently the Flex compiler would throw an error if you declared a style in the Skin and tried to use it on the component instance even though it's valid to declare that style and any other style in the CSS. What about if UIComponents had a style proxy object that let you set styles? Anyway, I digress.
If you want to make that style available on the TextInput instance in addition to the previous methods you can do that by extending TextInput and adding the cornerRadius style metadata to it. You can also set the skinClass (inline or in a defaults.css file in the library) while you're at it.
Something like this:
<?xml version="1.0" encoding="utf-8"?>
<s:TextInput xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
skinClass="TextInputRoundedSkin" >
<fx:Metadata>
[Style(name="cornerRadius", inherit="no", type="uint")]
</fx:Metadata>
</s:TextInput>
To use,
<local:MyExtendedTextInput cornderRadius="8" />
In the future you won't have to declare the CSS.
In the MX TabBar component, the iconField property allowed us to display different icons in each tab. In Spark, there does not seem to be an inherent way to add icons to the TabBar. Does anyone have an example of implementing icon support for Spark's TabBar? Is there a way to do this without extending the component?
Many thanks!
Hey after spending a week trying to follow multiple ways, (yours being top of the list) i found out a simpler and effective way to add icons to my tab bar, or any other component using skinning.
You dont need to create a custom component, just passing the icon and label through data.
http://cookbooks.adobe.com/post_Tutorials_for_skinning_Spark_ButtonBar_component_w-16722.html
As personally, i was using content navigator with my tabbar/viewstack, i passed the icon as icon instead of imageicon. you can make changes accordingly.
You'll have to create a skin for adding icons to Spark components; it is not as straightforward (IMHO) as Flex 3's MX components, though much more extensible.
Here are a few links which might help you get started:
Tour de Flex Tabbar examples
Custom Skin on Tabbar
Flex Tabbar with Skin
I believe I've come up with a solution, which I'm posting below for posterity. If anyone has a better way, I'd much appreciate the suggestion.
<!-- main app: TabBar implementation -->
<s:TabBar
dataProvider="{contentTabBarPrimaryDP}"
skinClass="skins.ContentTabBarSkin"/>
<!-- skins.ContentTabBarSkin: ItemRenderer implementation -->
<s:DataGroup id="dataGroup" width="100%" height="100%">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:itemRenderer>
<fx:Component>
<custom:IconButtonBarButton
label="{data.label}"
icon="{data.icon}"
skinClass="skins.ContentTabBarButtonSkin"/>
</fx:Component>
</s:itemRenderer>
</s:DataGroup>
<!-- skins.ContentTabBarButtonSkin: icon implementation -->
<s:HGroup
gap="3"
paddingBottom="3"
paddingLeft="3"
paddingRight="3"
paddingTop="3"
verticalAlign="middle">
<!--- layer 2: icon -->
<s:BitmapImage id="iconDisplay"
left="5"
verticalCenter="0" />
<!--- layer 3: label -->
<s:Label id="labelDisplay"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="1"
horizontalCenter="0" verticalCenter="1"
left="10"
right="10"
top="2"
bottom="2">
</s:Label>
</s:HGroup>
This solution uses a custom DTO object for the TabBar dataProvider which stores the label text as well as the embedded icon image as a class. I also had to extend the ButtonBarButton component to add an iconDisplay SkinPart, which looks like this:
[SkinPart(required="false")]
public var iconDisplay:BitmapImage;
This class also has getters/setters for the icon class property and sets the icon source, as such:
public function set icon(value:Class):void {
_icon = value;
if (iconDisplay != null)
iconDisplay.source = _icon;
}
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
if (icon !== null && instance == iconDisplay)
iconDisplay.source = icon;
}
It's seems to be a bug/missed functionality of the your SDK version:
http://forums.adobe.com/thread/552543
http://bugs.adobe.com/jira/browse/SDK-24331
Anyway, thanks for the solution with skins - very helpful