Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
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

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

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
07/25/2011 Flash Player Debug Issues - Safari 5.1 & Chrome 13
04/22/2012 Loader png - wrong color values in BitmapData
04/22/2012 HTTPService and crossdomain.xml doesn't work as expected
04/23/2012 Memory related crashes in Flex application

Flex Cookbook

More
04/06/2012 How to detect screen resize with a SkinnableComponent
02/29/2012 Embed Stage3D content inside Flex application components
02/15/2012 Custom WorkFlow Component
02/09/2012 Using Camera with a MediaContainer instead of VideoDisplay

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

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

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • 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
  • Security
  • 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
  • 台灣

Southeast Asia

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

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement