Not include component size in measure - apache-flex

I have a custom component that is basically a VBox with a Label and a TextField.
<mx:VBox width="50%">
<mx:Label width="100%"/>
<mx:TextField width="100%"/>
</mx:VBox>
What I want, basically, is to have two of these VBoxes layed out on a HBox and each would take exactly 50% - their children Label and TextField should just obey that.
If I set both Label and TextField's width to 100%, and the Label text doesn't fit, the default behaviour is to expands the VBox width - I don't want that to happen. The TextField should always take 100% of the width, and I'd want the Label to be explicitly set to the width of the TextField, so the text would be truncated and not expand the VBox width.
Is there a way to tell the Label to just obey the VBox (or TextField) width and not be included in the measurement of the VBox width?
Not sure if I was clear. :)
Thanks in advance.

it wasn't that easy as I thought. At the beginning I wanted to suggest maxWidth but it doesn't work correctly with label. However I just tested this:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.TextInput;
import mx.controls.Label;
private function onTextChanged(event:Event):void {
var currentText:String = TextInput(event.target).text;
var shortened:Boolean = false;
// adding 30 to leave some space for ...
while ( lbl.measureText(currentText).width > (lbl.width-30) ) {
currentText = currentText.substr(0,currentText.length-1);
shortened = true;
}
lbl.text = currentText + ((shortened) ? "..." : "" );
}
]]>
</mx:Script>
<mx:VBox width="50%">
<mx:Label id="lbl" width="100%" />
<mx:TextInput width="100%" change="onTextChanged(event);" />
</mx:VBox>
</mx:WindowedApplication>
It probably isn't written in a way (just attributed) you expected but it does what you need.
If this isn't a solution you could think of extending the Label in the following manner.
Crete custom Label:
radekg/MyLabel.as
package radekg {
import mx.controls.Label;
public class MyLabel extends Label {
public function MyLabel() {
super();
}
private var _myText:String;
override public function get text():String {
return _myText;
}
override public function set text(value:String):void {
if ( value != null && initialized ) {
// store the copy so the getter returns original text
_myText = value;
// shorten:
var shortened:Boolean = false;
while ( measureText(value).width > (width-30) ) {
value = value.substr(0,value.length-1);
shortened = true;
}
super.text = value + ((shortened) ? "..." : "");
}
}
}
}
And use it like that:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:controls="radekg.*">
<mx:VBox width="50%">
<controls:MyLabel width="100%" id="lbl" text="{ti.text}" />
<mx:TextInput width="100%" id="ti" />
<mx:Button label="Display label text" click="mx.controls.Alert.show(lbl.text)" />
</mx:VBox>
</mx:WindowedApplication>
This can be used simply with binding. Once you type very long text into the text input and the Label displays ... click on the button. You'll notice that text() getter returns original text.
Hope this helps.

Related

Flex Spark TextArea pinch&zoom?

My 1st question here...
Spark component TextArea does have a gestureZoom event property, but it seems that it has no functionality?
I would like to implement a simple zoom feature in my TextArea, which simply increases or decreases fontSize property, making text appear larger or smaller.
After implementing all the necessary code (and it works if instead of TextArea I use Image), pinch&zoom does not trigger the gestureZoom event on TextArea object.
Any suggestions? (I don't insist on using pinch&zoom, it just seems appropriate...)
Here 's the code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
applicationComplete="application1_applicationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.events.FlexEvent;
[Bindable]
public var currFontSize:int = 24;
protected function application1_applicationCompleteHandler(event:FlexEvent):void {
Multitouch.inputMode = MultitouchInputMode.GESTURE;
if(Multitouch.supportsGestureEvents){
txtbox.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onGestureZoom);
} else {
status.text="gestures not supported";
}
}
// THIS NEVER GETS CALLED?
private function onGestureZoom( event : TransformGestureEvent ) : void {
info.text = "event = " + event.type + "\n" +
"scaleX = " + event.scaleX + "\n" +
"scaleY = " + event.scaleY;
// Zomm in/out simply by increasing/decreasing font size
if (event.scaleX <1 || event.scaleY <1){
if (currFontSize > 12) currFontSize -=2;
}
else{
if (currFontSize < 64) currFontSize +=2;
}
}
protected function button1_clickHandler(event:MouseEvent):void {
info.text = "";
currFontSize = 24;
}
]]>
</fx:Script>
<s:Label id="status" top="10" width="100%" text="Transform Gestures on TextArea"
textAlign="center"/>
<s:HGroup left="12" right="12" top="40">
<s:TextArea id="info" width="100%" height="117" editable="false"/>
<s:Button label="Reset" click="button1_clickHandler(event)"/>
</s:HGroup>
<s:TextArea id="txtbox" left="12" right="12" bottom="12" height="400"
fontSize="{currFontSize}"
gestureZoom="onGestureZoom(event)"
text="Here is some sample text I want enlarged or shrunk."/>
</s:Application>
If the TextArea doesn't need to be editable.. see if you can use a Label. that should work with the pinch and zoom.

Flex: Binding to the Height of the UITextField

I'm having problems binding the height of a UITextField to the y of a VBox and the height of the TitleWindow. I'm trying to adjust the height of the TitleWindow and the height of the VBox so, that the UITextField doesn't overlap the other content.
Alternatively, I've tried setting the height of the UITextField to an explicit height, but I haven't been able to get it to work.
I have to use a UITextField instead of Text, because I'm using Flash Eff2.
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
width="520"
height="{tf.height + 380}">
<mx:Script>
<![CDATA[
import mx.core.UITextFormat;
import mx.events.ItemClickEvent;
import mx.controls.RadioButton;
import mx.controls.RadioButtonGroup;
import mx.core.UITextField;
import mx.managers.PopUpManager;
[Bindable]
public var tf:UITextField = new UITextField;
[Bindable]
public var myText:String;
[Embed(source="../libs/arial.ttf", fontFamily="ArialEmbedded")]
public const ArialEmbedded:Class;
public function createEffect2():void{
tf.autoSize = TextFieldAutoSize.LEFT;
//tf.height=150;
tf.embedFonts = true;
tf.multiline = true;
tf.text = myText;
tf.width = 400;
tf.wordWrap = true;
var myFormat:TextFormat = new TextFormat;
myFormat.size = 25;
myFormat.blockIndent=50;
this.addChild(tf);
tf.validateNow();
tf.setTextFormat(myFormat);
}
]]>
</mx:Script>
<mx:VBox x="180" y="{tf.height + 140}" width="480" >
<mx:RadioButtonGroup id="choicesRadioButtonGroup" />
<mx:RadioButton groupName="choicesRadioButtonGroup" label="A" horizontalCenter="150"/>
<mx:RadioButton groupName="choicesRadioButtonGroup" label="B" horizontalCenter="150"/>
<mx:RadioButton groupName="choicesRadioButtonGroup" label="C" horizontalCenter="150"/>
</mx:VBox>
</mx:TitleWindow>
I'm getting: Data Binding will not be able to detect assignments to "height".
Any suggestions?
Thank you.
-Laxmidi
If I had to guess, Binding is a Flex construct, not an "ActionScript' construct. Height is a made Bindable in UIComponent, but UITextField does not extend UIComponent. Instead it extends, FlexTextField, which extends TextField (A Closed source Flash class).
You can either extend UITextField and override height to make it Bindable or just use a Flex TextInput class, which does extend UIComponent.

PopUpButton with TileList and custom renderer

I have prepared a simple test case for a PopUpButton opening a TileList with black and red entries and it mostly works, but has 2 annoyances.
I've searched a lot, tried several variants (added [Bindable] members in my renderer; added color member to the bids array; created my public override set data() method; ...) and has been getting some answers too, but they are way too general.
I would appreciate if someone can suggest code to fix the 2 issues in my code:
1) Scrolling "tl2" right-left doesn't work well: the entries are displayed in a mix of red and black. I know the TileList reuses itemRenderer, but how do I fix the problem?
2) In debug-mode I get numerous warnings:
warning: unable to bind to property 'label' on class 'Object' (class is not an IEventDispatcher)
Thank you,
Alex
MyRenderer.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
width="100%" height="100%">
<mx:Script>
<![CDATA[
public static function findColor(str:String):uint {
return (str.indexOf('♥') != -1 ||
str.indexOf('♦') != -1) ? 0xFF0000 : 0x000000;
}
]]>
</mx:Script>
<mx:Label truncateToFit="true" width="60"
text="{data.label}" color="{findColor(data.label)}"/>
</mx:Canvas>
MyTest.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationPolicy="all" applicationComplete="init(event);">
<mx:Style>
#font-face {
src:url("C:\\WINDOWS\\Fonts\\arial.ttf");
fontFamily: myFont;
unicodeRange:
U+0020-U+0040, /* Punctuation, Numbers */
U+0041-U+005A, /* Upper-Case A-Z */
U+005B-U+0060, /* Punctuation and Symbols */
U+0061-U+007A, /* Lower-Case a-z */
U+007B-U+007E, /* Punctuation and Symbols */
U+0410-U+0451, /* cyrillic */
U+2660-U+266B; /* card suits */
}
List, CheckBox, Label, Button, PopUpButton, TileList {
fontFamily: myFont;
fontSize: 24;
}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.controls.*;
import mx.events.*;
[Bindable]
private var bids:Array;
private var tl:TileList;
private function init(event:FlexEvent):void {
bids = createBids();
pub.popUp = createList(bids);
}
private function createBids():Array {
var arr:Array = [{label: 'Pass'}];
for (var i:uint = 6; i <= 10; i++)
for (var j:uint = 0; j < 5; j++)
arr.unshift({label: i+'♠♣♦♥ '.charAt(j%5)});
return arr;
}
private function createList(arr:Array):TileList {
tl = new TileList();
tl.maxColumns = 5;
tl.width = 350;
tl.height = 250;
tl.dataProvider = arr;
tl.itemRenderer = new ClassFactory(MyRenderer);
tl.addEventListener('itemClick', itemClickHandler);
if (arr.length > 0) {
tl.selectedIndex = arr.length - 1;
pub.label = arr[tl.selectedIndex].label;
}
return tl;
}
private function itemClickHandler(event:ListEvent):void {
var index:uint = tl.columnCount * event.rowIndex + event.columnIndex;
var label:String = bids[index].label;
pub.label = label;
pub.setStyle('color', MyRenderer.findColor(label));
pub.close();
tl.selectedIndex = index;
}
]]>
</mx:Script>
<mx:Panel title="TileList scrolling problem" height="100%" width="100%"
paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">
<mx:Label width="100%" color="blue" text="Select your bid:"/>
<mx:TileList id="tl2" height="200" width="200"
maxColumns="5" rowHeight="30" columnWidth="60"
dataProvider="{bids}" itemRenderer="MyRenderer"/>
</mx:Panel>
<mx:ApplicationControlBar width="100%">
<mx:Spacer width="100%"/>
<mx:CheckBox id="auto" label="Auto:"/>
<mx:Button id="left" label="<<"/>
<mx:PopUpButton id="pub" width="90"/>
<mx:Button id="right" label=">>"/>
</mx:ApplicationControlBar>
</mx:Application>
Update:
Thank you Wade, the warning is gone now (I guess it was not ok to use {data.label} in my label), but the "tl2" still has scrolling issues.
New MyRenderer.mxml (still has scrolling issues):
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
width="100%" height="100%">
<mx:Script>
<![CDATA[
override public function set data(value:Object):void {
super.data = value;
var str:String = String(value.label);
myLabel.text = str;
myLabel.setStyle('color', findColor(str));
}
public static function findColor(str:String):uint {
return (str.indexOf('♥') != -1 ||
str.indexOf('♦') != -1) ? 0xFF0000 : 0x000000;
}
]]>
</mx:Script>
<mx:Label id="myLabel" truncateToFit="true" width="60"/>
</mx:Canvas>
You can take care of both of your issues by overriding the set data method on your item renderer:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
width="100%" height="100%">
<mx:Script>
<![CDATA[
override public function set data(value:Object):void {
super.data = value;
var str:String = value.label;
this.myLabel.text = str;
this.myLabel.setStyle("color", (str.indexOf('♥') != -1 ||
str.indexOf('♦') != -1) ? 0xFF0000 : 0x000000);
}
]]>
</mx:Script>
<mx:Label id="myLabel" truncateToFit="true" width="60"/>
</mx:Canvas>
Since the renderers are re-used, the best way to ensure they are correctly updated is to use the set data method since it always gets called when a renderer gets re-used. This also gets rid of your binding warning since you are no longer binding to data.label. Note: I haven't tested this code, it may need some tweaking :) Hope that helps.
EDIT: Your "tl2" issue looks like it's caused by horizontally scrolling your tile list, whereas the TileList appears to be optimized for vertical scrolling. Since your data set is finite and relatively small, I would make the tile list full size to show all of the elements (eliminating item renderer re-use) and wrap it in a canvas set to the desired dimensions and let the canvas handle the scrolling. Probably not the answer you are looking for, sorry.

Flex TextArea htmlText with stylesheet click bug

This bug is hard to describe, but easily reproduced with the bottom code. Just copy, paste, and compile+run in Flex 3 and you'll see the problem. Anyone know of a work around?
Edit: Here is a link to a running demo: http://shiinaringo.se/hosted/flex/textarea-bug/HtmlTextBug.html
In the demo, the default color of TextArea is set to red.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" applicationComplete="applicationComplete(event);">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
private function applicationComplete(event:Event):void {
var styles:String = "a:hover { color: #6666ff; text-decoration: underline; } a { color: #0000ff; }";
var ss:StyleSheet = new StyleSheet();
ss.parseCSS(styles);
textGreenStylesheet.styleSheet = ss;
}
private function enteredText(event:FlexEvent):void {
textDefault.htmlText = event.currentTarget.text;
textGreen.htmlText = event.currentTarget.text;
textGreenStylesheet.htmlText = event.currentTarget.text;
}
]]>
</mx:Script>
<mx:VBox height="100%" width="400" horizontalAlign="center">
<mx:Panel width="250" height="200" layout="absolute" title="TextArea A. Default colored text">
<mx:TextArea id="textDefault" condenseWhite="true" width="100%" height="100%" x="0" y="0">
<mx:htmlText>
<![CDATA[
This text has the default text color of the TextArea control.
]]>
</mx:htmlText>
</mx:TextArea>
</mx:Panel>
<mx:Panel width="250" height="200" layout="absolute" title="TextArea B. Green text">
<mx:TextArea id="textGreen" condenseWhite="true" width="100%" height="100%" x="0" y="0" color="green">
<mx:htmlText>
<![CDATA[
This text has the text color set to green
]]>
</mx:htmlText>
</mx:TextArea>
</mx:Panel>
<mx:Panel width="250" height="200" layout="absolute" title="TextArea C. Green text + stylesheet">
<mx:TextArea id="textGreenStylesheet" condenseWhite="true" width="100%" height="100%" x="0" y="0" color="green">
<mx:htmlText>
<![CDATA[
This text has the text color set to green, and also uses a stylesheet to make links blue and underlined when hovered.
]]>
</mx:htmlText>
</mx:TextArea>
</mx:Panel>
<mx:TextInput x="69" y="282" width="207" enter="enteredText(event);"/>
</mx:VBox>
<mx:VBox height="100%" width="200">
<mx:Text width="166" text="We have three TextArea controls. The top uses default text color, the middle one uses defined green text color, the bottom one also uses green color, but also uses a stylesheet to define some custom coloring of A tags." height="232"/>
<mx:Text width="166" text="To reproduce the problem, first try to just enter new text in the input field in the bottom, and press enter. The text in the three boxes will update. Notice that the colors and other styles don't change in any of the three boxes. But when you click once inside textarea C, then enter new text in the input field and hit enter, you'll notice that the color and font is lost in textarea C. Bug?" height="232"/>
</mx:VBox>
</mx:Application>
Basically, StyleSheet and TextFormat doesn't go together in a flash textfield.
Following is my guestimate of what might be happening:
The color="green" will become part of the defaultTextFormat of the internal TextField of the TextArea and will be applied to the text well before applicationComplete is fired. You can verify this by tracing trace(textGreenStylesheet.htmlText); in the application complete handler (before you set the stylesheet). Here is what I got:
<TEXTFORMAT LEADING="2"><P ALIGN="LEFT"><FONT FACE="Verdana" SIZE="10" COLOR="#008000" LETTERSPACING="0" KERNING="0">This text has the text color set to green, and also uses a stylesheet to make links blue and underlined when hovered. </FONT></P></TEXTFORMAT>
Now when you apply the stylesheet, the color remains unchanged (green) as the stylesheet do not specify any color for the whole text.
When you click on the TextArea, I believe flex recalculates properties of it (may be click triggers an invalidation - I am not sure what's happening underneath). While doing this, compiler finds that a stylesheet has been applied and ignores the color="green" attribute. Now, these new properties are applied only when the text/htmltext property is changed (later by hitting enter). So unless you click or somehow trigger an invalidation of textarea, it retains the default color specified before applying the stylesheet.
If you add .yellow{color:#ffff00;} to the stylesheet and enclose some text in the third text area with <span class="yellow">some text</span> tags, you can see that the enclosed text retains yellow color whether you click on it or not.
Here's what I'm doing to resolve this. It's a big hack, but it does work.
import flash.events.Event;
import flash.text.TextFormat;
import mx.controls.Text;
import flash.text.StyleSheet;
import mx.core.mx_internal;
import mx.events.FlexEvent;
public class SupText extends Text
{
use namespace mx_internal;
public var linkColor:String = "#355EBF";
private var format:TextFormat;
public function SupText()
{
super();
this.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void { setStyleSheet(); });
}
override public function set htmlText(value:String):void {
if (format != null) {
//glorious hack for style problem
textField.styleSheet = null;
textField.defaultTextFormat = format;
setStyleSheet();
}
super.htmlText = value;
if (textField.defaultTextFormat.font != "Times New Roman") {
format = textField.defaultTextFormat;
}
}
public function setStyleSheet():void {
var ss:StyleSheet = textField.styleSheet;
if(textField.styleSheet == null){
textField.styleSheet = new StyleSheet();
}
textField.styleSheet.setStyle("sup", { display: "inline", fontFamily: "ArialSup", fontWeight:"normal"});
textField.styleSheet.setStyle("a:link", { textDecoration: "none", color: linkColor });
textField.styleSheet.setStyle("a:hover", { textDecoration: "underline" });
textField.styleSheet.setStyle("a:active", { textDecoration: "underline" });
}
}
}
Can you assign the text directly to the .text property?
private function enteredText(event:FlexEvent):void
{
textDefault.text = event.currentTarget.text;
textGreen.text = event.currentTarget.text;
textGreenStylesheet.text = event.currentTarget.text;
}

Flex/Accordion: Conditionally hide a child

How do I hide a child in a accordion? Using visible doesn't seem to work and enabled isn't what I'm after.
<mx:Accordion>
<mx:VBox width="100%" height="100%" label="Foo" id="viewOverview" visible="false">
...
</mx:VBox>
...
</mx:Accordion>
I think you can't hide it. Strange that the visible property doesn't work... Anyway, I would control the children through code and remove and insert them as needed by the app. Hiding:
function hideFoo():void {
this.theAccordion.removeChild(this.vboxFoo);
}
You'll probably want to keep a reference to the "hidden" child so that you can add it later again.
This isn't an answer, just some curious things I found out while trying to find another solution to this problem:
Accordion headers have a visible property and a setActualSize method. The latter takes a height and width, and setting each to zero...
acc.getHeaderAt(0).setActualSize(0,0);
...accomplishes the same thing as setting visible = false, that is it hides the contents of the header, but does not remove its area from the accordion. I was hoping to trick the accordion into hiding the child, but no such luck...nonetheless, it might be a path to continue to try. If I get more time I will continue to explore but I'm out of bandwidth at the moment...
You can also create a descendant of accordion with methods like showHeader, hideHeader, isHeaderHidden that contains hash table to keep track of hidden elements similar to the one below:
public class AccordionHideHeader extends Accordion
{
private var _hiddenHeader:Dictionary=new Dictionary();
public function AccordionHideHeader()
{
super();
}
public function hideHeader(header:DisplayObject):void
{
if (contains(header))
{
_hiddenHeader[header]=getChildIndex(header);
removeChild(header);
}
}
public function showHeader(header:DisplayObject):void
{
if (!contains(header))
{
addChildAt(header, _hiddenHeader[header]);
delete _hiddenHeader[header]
}
}
public function isHeaderHidden(header:DisplayObject):Boolean
{
for (var key:Object in _hiddenHeader)
{
if (key==header)
return true;
}
return false;
}
}
Sorry I'm not agree with removing child, because you will having problem when adding it back to its position in exact order.
Example: If you have 5 page in accordion, you remove child 1 and 3, now in any condition you want number 3 back to acordion how do you put it back? because the index is not 3 anymore (rember that 1 is removed too).
I found a good solution here. In short you make your own acordion with enalbe and disable ability where enable and disable define on the child container.
here i paste the acordion code:
/**
* http://blog.flexexamples.com/2008/05/30/preventing-users-from-clicking-on-an-accordion-containers-header-in-flex/
*/
package comps {
import mx.containers.accordionClasses.AccordionHeader;
import mx.events.FlexEvent;
public class MyAccHeader extends AccordionHeader {
public function MyAccHeader() {
super();
addEventListener(FlexEvent.INITIALIZE, accordionHeader_initialize);
}
private function accordionHeader_initialize(evt:FlexEvent):void {
enabled = data.enabled;
}
}
}
Maybe my answer not relevant anymore for you, but i hope can help someone else who face the same problem.
You can override Accordion logic and user includeInLayout property to control visibility of children.
This will work if you set all children in MXML.
import flash.events.Event;
import mx.containers.Accordion;
import mx.core.UIComponent;
public class DynamicAccordion extends Accordion
{
public function DynamicAccordion()
{
}
private var allChildern:Array;
override protected function childrenCreated():void
{
allChildern = new Array();
for (var i:int = numChildren - 1; i >= 0 ; i--)
{
var child:UIComponent = getChildAt(i) as UIComponent;
if (child)
{
child.addEventListener("includeInLayoutChanged", childIncludeLayoutChangedHandler);
if (!child.includeInLayout)
{
removeChild(child);
}
allChildern.push(child);
}
}
allChildern = allChildern.reverse();
super.childrenCreated();
}
private function childIncludeLayoutChangedHandler(event:Event):void
{
var child:UIComponent = event.currentTarget as UIComponent;
if (child.includeInLayout)
{
var index:int = allChildern.indexOf(child);
addChildAt(child, index);
}
else
{
removeChild(child);
}
}
}
I think you might have to actually remove the accordion child itself (e.g. using the State removeChild() mechanism). If you need to preserve the object itself, just keep a reference to it in a global variable.
Cheers
Accordion controls always have 1 child open. By opening another child, the current one will close.
If you want to have more than 1 child open at a time or have all children closed, you can use the VStack component available at: http://weblogs.macromedia.com/pent/archives/2007/04/the_stack_compo.html
<mx:Script>
<![CDATA[
private function hideFn():void
{
acc.removeChildAt(0);
}
private function showFn():void
{
acc.addChildAt(helloBox , 0);
}
]]>
</mx:Script>
<mx:VBox>
<mx:Accordion id="acc" width="200" height="200">
<mx:VBox id="helloBox" label="Test">
<mx:Label text="hello"/>
</mx:VBox>
<mx:VBox label="Test2">
<mx:Label text="hello again"/>
</mx:VBox>
</mx:Accordion>
<mx:Button label="hide" click="hideFn()"/>
<mx:Button label="show" click="showFn()"/>
</mx:VBox>
Here my solution :
http://weflex.wordpress.com/2011/01/25/flex-accordion-hideshow-headers/
I copied and modified the code of the Accordion, so if a child has its "includeInLayout" property to false, it won't be displayed.
Try this one
accrod.getHeaderAt(0).enabled=false;
accrod.getHeaderAt(0).visible=false;
Here is the solution, how to collapse the accordion on click of header.
<mx:Script>
<![CDATA[
import mx.events.IndexChangedEvent;
private var isAccordionClosed:Boolean;
private function myAccordion_clickHandler(event:MouseEvent):void
{
trace(event.currentTarget.label);
var selIdx:int = myAccordion.selectedIndex;
isAccordionClosed = (isAccordionClosed) ? false : true;
if (isAccordionClosed)
{
collapseAccordion(selIdx, !isAccordionClosed);
}
else
{
collapseAccordion(selIdx, !isAccordionClosed);
}
}
private function collapseAccordion(idx:int, showHide:Boolean):void
{
switch(idx)
{
case 0:
vb1.scaleX = vb1.scaleY = int(showHide);
break;
case 1:
vb2.scaleX = vb2.scaleY = int(showHide);
break;
case 2:
vb3.scaleX = vb3.scaleY = int(showHide);
break;
case 3:
vb4.scaleX = vb4.scaleY = int(showHide);
break;
case 4:
vb5.scaleX = vb5.scaleY = int(showHide);
break;
}
}
private function myAccordion_changeHandler(event:IndexChangedEvent):void
{
isAccordionClosed = true;
}
]]>
</mx:Script>
<mx:Accordion id="myAccordion" x="200" y="200" click="myAccordion_clickHandler(event)" resizeToContent="true"
width="399" verticalGap="0" change="myAccordion_changeHandler(event)">
<mx:VBox id="vb1" label="Chapter 1">
<mx:Label text="Accordion 1" width="397" textAlign="center" height="38"/>
</mx:VBox>
<mx:VBox id="vb2" label="Chapter 2">
<mx:Label text="Accordion 2" width="397" textAlign="center" height="43"/>
</mx:VBox>
<mx:VBox id="vb3" label="Chapter 3">
<mx:Label text="Accordion 3" width="397" textAlign="center" height="43"/>
</mx:VBox>
<mx:VBox id="vb4" label="Chapter 4">
<mx:Label text="Accordion 4" width="397" textAlign="center" height="43"/>
</mx:VBox>
<mx:VBox id="vb5" label="Chapter 5">
<mx:Label text="Accordion 5" width="397" textAlign="center" height="43"/>
</mx:VBox>
</mx:Accordion>

Resources