Set Spark button width in ButtonBar - apache-flex

How do I set the individual button sizes in a Spark ButtonBar? It used to be something like:
<mx:ButtonBar id="myButtonBar" buttonHeight="12" buttonWidth="250" >
I get an error when I try to do the same in Spark:
Cannot resolve attribute 'buttonHeight' for component type spark.components.ButtonBar
I don't want to create a separate skin...just something that will work inline if possible

Just set its layout.
<s:ButtonBar id="myButtonBar">
<s:layout>
<s:HorizontalLayout variableColumnWidth="false" gap="0" columnWidth="250"/>
</s:layout>
</s:ButtonBar>
Many things are just different in Spark :)

I see two different ways to approach this.
Create a custom skin class and set the Button Width that way. You'll have to review the existing ButtonBar Skin to figure out specifics.
Extend the button class to set he new button width and use that class to create new factories for the button related skin parts
You could also roll back to the Flex 3 ButtonBar and use the buttonWidth style. Some things are just easier in Halo.

Related

TitleWindowSkin, TitleWindowCloseButtonSkin, colorization: how do I duplicate this behavior in a custom component?

I am trying to use the spark.skins.spark.TitleWindowCloseButtonSkin in a custom component and make it look thematically similar to how it looks in TitleWindow. Just specifying it as the skin class for a Button works no problem. I also have a .css style applied to all my TitleWindow classes that affects the close buttons in a TitleWindow. If I set the chrome color of the TitleWindow in .css then the close button skin also gets colorized to match this color. My custom component is also using the same style reference as my TitleWindows. But the Button instance inside of my custom component does not get colorized. So while I have blue TitleWindows with blue-colorized closed buttons, I have a blue custom component with a default gray background closed button (on button-press, the gray background appears).
There must be something going on with TitleWindowSkin and TitleWindowCloseButtonSkin via the colorization mechanic but I don't understand what it is. How should I solve this problem? I need to make the close button style in my custom component match that of the close button in my TitleWindows.
Here is a picture of the problem:
The TitleWindow is on the left in both pictures. The custom component is on the right.
In the left frame, you see the TitleWindow close button in the down position, note that its down state is colorized to match the theme of the TitleWindowSkin. On the right you see the down state of the custom component's close button. I do not know how to colorize the default gray to match the blue theme applied to the custom component.
I am sure there are a multitude of ways to solve this. I am looking for the most "correct" way. I do not want to hard-code colors because later an actual designer will come in and tweak the .css.
PS My custom component extends from spark.components.Group. Could that be a problem???
I should also mention that normal Button instances that use the default spark ButtonSkin do seem to get styled properly in the custom component (part of the reason this problem is so frustrating).
EDIT: yes, yes indeed it looks like the first step to a solution is to inherit from SkinnableComponent not Group or UIComponent...
In your TitleWindowSkin you need to add "closeButton" in exclusions array at top, I have resolved the same issue with this.
hm, this is curious since I can't seem to find any reference to chrome color or anything within the close button skin:
<s:Rect left="0" top="0" right="0" bottom="0">
<s:stroke>
<s:SolidColorStroke color="0x000000"
alpha="0.0"
alpha.over="0.7"
alpha.down="0.7"
weight="1"/>
</s:stroke>
<s:fill>
<s:SolidColor color="0xCCCCCC" alpha="0" alpha.down="0.7" />
</s:fill>
</s:Rect>
If I were you, I'd just create a skin based on the close button skin and have a reference to a style color using getStyle which can be changed in the css.
Ok, so I have mostly figured out the problem. It stems from the fact that I am not using a proper skin technique on my custom component. The custom component logic is fine where it is at, but I need to prepare a separate skin class that actually instantiates the custom component's "parts" (ie: sub-components). Currently, the custom component does this in createChildren(). Furthermore, to take advantage of the colorization mechanic, the skin class must inherit from SparkSkin. The TitleWindowCloseButton instance needs to be a member of the custom component's skin class (as well as having a reference in the custom component class). SparkSkin will automatically color transform (colorize) every child of the custom component's skin unless it is explicitly excluded. Finally, back in the custom component, override partAdded() and when "closeButton" comes up, add the close button's event handler at that time. Feels very Cairngorm-ey... but I digress (must suppress urge to rant about the stoopid that are "helper" classes).

Horizontal List or Carousel for Flex mobile?

Im creating a person search interface in Adobe Flex / Actionscript where we have an image for each person and a bit of text. Im looking to implement some like this:
HorizontalList Interface
OR
Carousel Interface
Both of these packages are unfortunately only for desktop Flex, I was wondering if anyone knew mobile flex (particularly Blackberry Playbook) alternatives?
Thanks
Phil
If you're using the standard s:List, you can change its layout property to a HorizontalLayout instance.
Basically, something like this:
<s:List>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:List>
Maybe you could use a TileList instead. This is a horizontal list that automatically uses the next row if the page is full. You can fill it with data by using the DataProvider tag.
Here is an example:
<mx:TileList id="tileList" borderStyle="none" paddingBottom="0"
paddingTop="5" paddingLeft="5" paddingRight="5" itemClick="onClickHandler(event)"
dataProvider="{yourArrayList}" itemRenderer="renderer.WidgetRenderer" />
The class widgetrenderer creates my imageButtons (so normal images can be used too). These buttons are made of the data in my arraylist that can be approached by data.(the item in the arraylist his properties) If you need the clicked item you can use the id of your tilelist and choose for selected item.
In this example:
var object:Object = tileList.selectedItem;
I don't know if you understand my explanation, if not feel free to ask.
I hope this could help you.
There is a perfect example of this in tour de flex that uses a custom layout with the postLayoutTransform properties to build the 3d effect.
I don't know how to link to the specific example, but if you go here just click on Other Components -> Layouts -> Carousel
Cheers!
Horizontal List should work fine on mobile!

Extending DataGrid component, and adding buttons to it

I'd like to extend the standard DataGrid component in flex with mxml. But I want to add buttons to the bottom of the component. I've tried attempting the following but its not working...
Am I adding the Button to the wrong element?
<mx:DataGrid xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:mx = "library://ns.adobe.com/flex/mx"
xmlns:s = "library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
override protected function createChildren():void
{
super.createChildren();
listContent.addChild(button);
}
]]>
</fx:Script>
<s:Button id="button" label = "asdasdas"/>
</mx:DataGrid>
You need to define "Not working"! Are you getting compiler errors? Or runtime errors? Or is the button just not showing up? I'll assume the latter.
The DataGrid does not have any mechanism for positioning or laying out it's children. Your button most likely has a height and width of zero and resides at position 0,0; making it effectively invisible. Many Flex container classes have the ability to size and position their children; but the DataGrid is not a container and does not provide built in functionality for that. It focuses, primarily, on working with the columns array.
You will need to override the updateDisplayList() to position the function. Quite possibly you will need to make changes to commitProperties() and measure() along the way. You may also need to re-work how the columns are positioned and sized as to not interfere with your new button. If stuff is locked away in private methods (which is probable) then you're in a for a not-so-fun-time.
Read up on the Flex Component LifeCycle methods for more information and also review the DataGrid code to figure out what it does.
You may have an easier time just putting the button and DataGrid in a container, and treating that container as a single entity instead of trying to get a Button renderered inside of the DataGrid.
Got it. All I needed to do was replace listContent.addChild(button); with...
parent.addChild(button);
Thanks!

Flex 4.1: <mx:List> had rowCount properly for the limit the displayed items. <s:List> doesn't

Hi I'm using flex 4.1 to write an application.
i read in the documents that has the rowCount property to set how many items to display. the does not have that property.
how can I limit the list to display 3 items ?
you can directly set requestedMinRowCount to 3 in the VerticalLayout
<s:List>
<s:layout>
<s:VerticalLayout requestedMinRowCount="3"/>
</s:layout>
</s:List>
In Flex 4 this is driven by the skin rather than the component itself. You can create a custom List skin and in the VerticalLayout of the DataGroup, set the requestedRowCount to 3, then set the skin for your List to be your new custom skin. To get started, just copy the default ListSkin into your custom skin file and make your changes. Here's the relevant section from the default ListSkin file:
<s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<!--- The default layout is vertical and measures at least for 5 rows.
When switching to a different layout, HorizontalLayout for example,
make sure to adjust the minWidth, minHeihgt sizes of the skin -->
<s:VerticalLayout gap="0" horizontalAlign="contentJustify" requestedMinRowCount="5" />
</s:layout>
</s:DataGroup>
Just remove requestedMinRowCount and replace it with requestedRowCount="3" Hope that helps.
Thanks Wade for the great answer, it put me on the right path.
Actually you don't need to copy the default skin, if it's only the row count you want to fix Just use the tag inside the tag to control the minimum row count like Wade described.

How can I animate between states in a programmatic skin? [FLEX]

I have a button with the various states (up/over/down etc) that uses a skin file to render the display. I want to achieve animation between the states. For instance, between the change from 'up' to 'over' I want to fade in a color and a border.
The way I am doing this at the moment is to use viewstates and animate between them using transitions and the mx:AnimateProperty. However, using this method I can only animate one property per viewstate. So only the border, or the color can be animated.
Does anyone know how I can achieve multiple animations on multiple properties of a programmatic button skin? Thanks in advance!
Note: I have looked into using tweener but cannot see how it would help my situation
http://www.degrafa.org/
http://www.degrafa.org/source/AdvancedSkins/Skins.html
Lewis,
You will not be able to animate any properties of a ProgammaticSkin in Flex 3 because the way UIComponent does skins is by instantiating an entire new instance of your skin and then setting its name property. Then when the component needs to display a new state, it makes another new instance, sets its name property to something different, makes the old skin invisible and makes the new skin visible. In this way, it "caches" the skins, instead of switching states and redrawing in UpdateDisplayList.
Now because of that you can't easily animate any drawing of the skin itself, however, there is a solution although it's not entirely elegant.
ProgammaticSkin extends FlexShape, so you can't add any children to your skin, but UIComponent looks for something that implements IProgrammaticSkin, so you can make your own ProgrammaticSkin that extends FlexSprite instead of FlexShape. This allows you addChild to your skin. If you are clever enough, you can synchronize transitions between the various cached skins to make them animatable.
Hope that helps,
Jonathan
Since you use skin files I suppose you use Flex4.
In Flex4, you can use multiple mx:AnimatePropery declarations wrapped in a s:Sequence or s:Parallel node.
<s:transitions>
<s:Transition>
<s:Parallel>
<mx:AnimateProperty
target="{button}"
property="property1"
fromValue="property1StartValue"
toValue="property1EndValue" />
<mx:AnimateProperty
target="{button}"
property="property2"
fromValue="property2StartValue"
toValue="property2EndValue" />
</s:Parallel>
</s:Transition>
</s:transitions>

Resources