Adobe
Products
Creative Suite
Photoshop Family
Acrobat Family
Flash Platform
Digital Marketing Suite
Digital Publishing Suite
More products
Solutions
Digital marketing solutions
Digital media solutions
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Store
Adobe Store for home and home office
Education Store for students, educators, and staff
Business Store for small and medium businesses
Other ways to buy
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections   Search  
Solutions Company
Help Learning
Sign in Welcome, My orders My Adobe
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flex Developer Center /

Understanding Flex itemRenderers – Part 4: States and transitions

by Peter Ent

Peter Ent
  • Adobe

Content

  • States
  • Adding elements
  • Expanding list items

Created

14 October 2008

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
Flex states

Requirements

Prerequisite knowledge

To benefit most from this article, it is best if you are familiar with Flex Builder and ActionScript 3.0.

User level

Beginning

Required products

  • Flex Builder 3 (Download trial)

Communicating with the user of your application is what your itemRenderer does best. Sometimes that communication is as simple as presenting a name; sometimes more elaborately using colors; and sometimes with interactivity.

itemEditors are truely interactive controls, but they are not the focus of this article. In these examples I'll demonstrate itemRenderers that change their visual appearance based on either the data itself or the user's actions.

This series includes the following articles:

  • Part 1: Inline renderers
  • Part 2: External renderers
  • Part 3: Communication
  • Part 4: States and transitions
  • Part 5: Efficiency

States

The Flex <mx:State> is a very good way to change the appearance of an itemRenderer. States are easy to use, and when combined with transitions, give the user feedback and pleasent experience.

In this example, you'll create a new MXML itemRenderer (and remember, you can do this completely in ActionScript if you prefer) for the list. All this itemRenderer shows is the image, title, author, price, and a Button to purchase the book.

<?xml version="1.0" encoding="utf-8"?> <mx:HBox xmlns:mx="/2006/mxml"> <mx:Image id="bookImage" source="{data.image}" /> <mx:VBox height="115" width="100%" verticalAlign="top" verticalGap="0" paddingRight="10"> <mx:Text text="{data.title}" fontWeight="bold" width="100%"/> <mx:Label text="{data.author}" /> <mx:HBox id="priceBox" width="100%"> <mx:Label text="{data.price}" width="100%"/> <mx:Button label="Buy" /> </mx:HBox> </mx:VBox> </mx:HBox>

What you want, however, is, if the book is not in stock (the data has <instock> nodes that are either yes or no) the price and "Buy" Button will be invisible. I've made things a bit convenient for coding here by giving the HBox parent of the price and Button an id property. This allows me to change the visibility of both of those items by changing the visibility of the HBox, priceBox.

You can do this by overridding the set data function, which you'll do, but instead of directly changing the visibility of priceBox, you'll use this state defintion:

<mx:states> <mx:State name="NoStockState"> <mx:SetProperty target="{priceBox}" name="visible" value="false"/> </mx:State> </mx:states>

Place this just below the root <mx:HBox> tag.

This example is a bit far-fetched in that it is overly complicated to do a simple task, but it shows how to use states. There are two states:

  • The base state: this is the normal state of a component. Components that do not use states simply have this base state. In this example, the base state has the priceBox visible property as true (the default). This is the case when instock is yes.
  • The NoStockState: this is the state when the value of instock is no. When this state is active, the SetProperty instructions are carried out. The target property determines which member of the class is in question, the name property is the name of the property to change on the target, and value is the new value for the property.

The set data function determines which state to use by looking at the value of instock:

override public function set data( value:Object ) : void { super.data = value; if( data ) { if( data.instock == "yes" ) currentState = ""; else currentState = "NoStockState"; } }

The currentState is a property of all UIComponent controls. It determines which state is the active one. When switching between states, the Flex framework begins with the base state and then applies the rules for the given state.

Note: Remember that itemRenderers are recycled, so you must always restore values; never leave an if without an else in an itemRenderer.

If you are feeling adventurous, you can do away with the set data override in this example. Instead, set currentState directly in the root tag by using a data binding expression:

<mx:HBox xmlns:mx="/2006/mxml" width="400" currentState="{data.instock == 'yes' ? '' : 'NoStockState'}" >

The currentState's value is set by examining data.instock right inline with the root tag–a nice trick, but it might be harder to maintain.

Adding elements

In this itemRenderer, the price and Buy button appears only if the instack value is yes. You could do this without a state, of course, but if your itemRenderer has more controls to be added or removed, a state will make more sense as the controls' appearance can be controlled simply by setting the itemRenderer's currentState property.

Instead of just removing the price and Button, you'll have the state add a label telling the user the item is out of stock. Here's the modified state:

<mx:states> <mx:State name="NoStockState"> <mx:SetProperty target="{priceBox}" name="visible" value="false"/> <mx:AddChild relativeTo="{priceBox}" position="before"> <mx:Label text="-- currently not in stock --" color="#73DAF0"/> </mx:AddChild> </mx:State> </mx:states>

The <mx:AddChild> tag says to add the Label into the priceBox. In addition to setting the priceBox's visible property to false, a friendly message replaces it.

Again, you could add this label in the set data function–or add it initially and just set its visibility to false and change it to true in the set data function. But I think you can see the value of the state: if the requirement for the instock being no condition gets more complex, all you need to do is adjust the NoStockState; the ActionScript code which switches the state remains the same.

Note: You can modify states in Flex Builder's Design View.

Expanding list items

This example does not work well for List controls, but does perform nicely for a VBox and Repeater. This question of expanding an item in place becomes dicey when the list has to be scrolled. Imagine this: you've got a list of items with all the same height. Now you expand the height of item 2. So far so good: item 2 is taller than the other visible items. And there's the catch: the visible items. Now scroll the list. Remember that itemRenderers are recycled. So when item 2 scrolls out of view, its itemRenderer will be moved to the bottom of the list. You've got to reset its height. OK, that can work pretty simply. Now scroll the list so item 2 is back in view. You would expect it to be the expanded height. How does the itemRenderer know to do that? From previous articles, you know that information either comes from the data itself or from some external source.

I think a resizing itemRenderer is too complex and not really worth the effort. I believe there is a better way to do this using VBox and Repeater. However, the catch with Repeater is that every child will be created. If you have 1000 records and use a Repeater, you will get 1000 instances of your itemRenderer.

For this example you'll still write an itemRenderer, but will use it as the child of a VBox. The elements of a list look pretty simple: the name of a book and its author. But click the itemRenderer and it expands in place. This is accomplished using two tactics:

  • The itemRenderer has a state that includes the additional information.
  • The itemRenderer uses a Resize transition to give a smoother expansion and contraction of the itemRenderer.

The base state of the itemRenderer is pretty simple:

<mx:HBox width="100%"> <mx:Label text="{data.author}" fontWeight="bold"/> <mx:Text text="{data.title}" width="100%" fontSize="12" selectable="false"/> </mx:HBox>

The ExpandedState adds the additional elements which contribute to the itemRenderer's height:

<mx:states> <mx:State name="ExpandedState"> <mx:AddChild position="lastChild"> <mx:HBox width="100%"> <mx:Image source="{data.image}"/> <mx:Spacer width="100%"/> <mx:Label text="{data.price}"/> <mx:Button label="Buy"/> </mx:HBox> </mx:AddChild> </mx:State> </mx:states>

Getting the itemRenderer to change size is as simple as adding a transition:

<mx:transitions> <mx:Transition fromState="*" toState="*"> <mx:Resize target="{this}" /> </mx:Transition> </mx:transitions>

Place this below the <mx:states> tag.

The transition is applied whenever the state changes, because its fromState and toState properties are wildcards. Now all you have to do is add an event handler for clicking the itemRenderer (add a click event to the root tag) and change the state:

<mx:Script> <![CDATA[ private function expandItem() : void { if( currentState == "ExpandedState" ) currentState = ""; else currentState = "ExpandedState"; } ]]> </mx:Script>

Where to go from here

States are a great way to make a number of modifications to the visual appearance of the itemRenderer. You can group the changes in a State and simply make it all happen by setting the currentState property of the itemRenderer.

In the next article we'll look at writing more efficient itemRenderers by extending UIComponent.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License

More Like This

  • Flex quick start guide for HTML and PHP developers
  • Differences between Flex 3 and Flex 4
  • What's new in Flex 4
  • Using Flex effects to animate changes in application state
  • Managing application state with Flex 3

Tutorials & Samples

Tutorials

  • Flex mobile performance checklist
  • Flex and Maven with Flexmojos – Part 3: Journeyman
  • Migrating Flex 3 applications to Flex 4.5 – Part 4

Samples

  • Twitter Trends
  • Flex 4.5 reference applications
  • Mobile Trader Flex app on Android Market

Flex User Forum

More
02/07/2012 Newbie - Views
01/24/2012 How to navigate through the views without losing content?
02/07/2012 ActionScript rounding issue
02/07/2012 Setting Value of Static Const

Flex Cookbook

More
01/20/2012 Skinnable Transform Tool
12/12/2011 Date calculations using 'out-of-the-box' functions
12/05/2011 String replaceAll in ActionScript
12/04/2011 Flex: Validate/revert editable Datagrid input value

Products

  • Creative Suite
  • Photoshop Family
  • Acrobat Family
  • Flash Platform
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Mobile apps

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • Adobe Store
  • For students and educators
  • For small and medium businesses
  • For enterprises
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • Pacific - English
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy (updated 07-14-2009).

Ad Choices

Reviewed by TRUSTe: site privacy statement