Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
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 / Flex Test Drive /

Flex Test Drive: Change the appearance of your application

by Adobe

Adobe logo

Modified

27 June 2011

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
Flash Builder Flex RIA

Video | Code | Tutorial | Links

Create skins

 

This content requires Flash To view this content, JavaScript must be enabled, and you need the latest version of the Adobe Flash Player. To view this content, JavaScript must be enabled, and you need the latest version of the Adobe Flash Player.

Download the Test Drive solution files (ZIP, 14 MB)
Download the assets files for this tutorial (ZIP, 2 KB)

Code

TestDrive.mxml

@namespace s "library://ns.adobe.com/flex/spark"; (...) s|TextInput.searchInput { skinClass: ClassReference("skins.SearchInputSkin"); } s|Button.searchButton { skinClass: ClassReference("skins.SearchButtonSkin"); }

FlexWebTestDrive.mxml

<s:Application ...> (...) <s:TextInput id="searchTxt" prompt="Last Name" styleName="searchInput" .../> <s:Button id="searchBtn" styleName="searchButton" .../> </s:Application>

skins/SearchInputSkin.mxml

<?xml version="1.0" encoding="utf-8"?> <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabledStates="0.5" blendMode="normal" minHeight="30"> <fx:Metadata> [HostComponent("spark.components.TextInput")] </fx:Metadata> <fx:Script> <![CDATA[ private static const focusExclusions:Array = ["textDisplay"]; override public function get focusSkinExclusions():Array { return focusExclusions; }; ]]> </fx:Script> <s:states> <s:State name="normal"/> <s:State name="disabled" stateGroups="disabledStates"/> <s:State name="normalWithPrompt"/> <s:State name="disabledWithPrompt" stateGroups="disabledStates"/> </s:states> <s:Rect id="border" left="0" right="0" top="0" bottom="0" radiusX="3" radiusY="3"> <s:stroke> <s:SolidColorStroke id="borderStroke" weight="1" /> </s:stroke> </s:Rect> <s:Rect id="background" left="1" right="1" top="1" bottom="1" radiusX="3" radiusY="3"> <s:fill> <s:SolidColor id="bgFill" color="0xFFFFFF" /> </s:fill> </s:Rect> <s:Rect id="shadow" left="1" top="1" right="1" height="1" radiusX="3" radiusY="3"> <s:fill> <s:SolidColor color="0x000000" alpha="0.12" /> </s:fill> </s:Rect> <s:RichEditableText id="textDisplay" verticalAlign="middle" widthInChars="10" left="10" right="10" top="10" bottom="7" /> <s:Label id="promptDisplay" maxDisplayedLines="1" verticalAlign="middle" mouseEnabled="false" mouseChildren="false" includeIn="normalWithPrompt,disabledWithPrompt" includeInLayout="true" fontStyle="normal" left="10" right="10" top="10" bottom="7"/> </s:SparkSkin>

skins/SearchButtonSkin.mxml

<?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:assets="assets.*" minHeight="30" minWidth="30"> <fx:Metadata> [HostComponent("spark.components.Button")] </fx:Metadata> <s:states> <s:State name="disabled" /> <s:State name="down" /> <s:State name="over" /> <s:State name="up" /> </s:states> <s:Rect left="0" right="0" top="0" bottom="0" topRightRadiusX="3" topRightRadiusY="3" bottomRightRadiusX="3" bottomRightRadiusY="3"> <s:stroke> <s:SolidColorStroke color="#1A1A1A" weight="1"/> </s:stroke> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0x999999" color.up="0x666666"/> <s:GradientEntry color="0x4D4D4D" color.up="0x333333"/> </s:LinearGradient> </s:fill> </s:Rect> <assets:search_icon horizontalCenter="0" verticalCenter="0"/> <!-- SkinParts name=iconDisplay, type=spark.primitives.BitmapImage, required=false name=labelDisplay, type=spark.core.IDisplayText, required=false--> </s:Skin>

Tutorial

In this tutorial, you learn to change the appearance of components by creating and using skins. You will skin the TextInput and Button controls used to search the employees. To customize the look and layout of the TextInput control, you create a new skin based on its default skin and then modify it. For the search button, you create a completely new skin and then add graphics to it.

Step 1: Create a new skin for the TextInput control.

Return to Design mode of FlexWebTestDrive.mxml. Select the searchTxtTextInput control. In the Properties view, click the button next to the Skin field and select Create Skin (see Figure 1). In the New MXML Skin dialog box, set the package to skins and the name to SearchInputSkin; leave the host component set to spark.components.TextInput, create it as a copy of spark.skins.spark.TextInputSkin, and remove the ActionScript styling code (see Figure 2).

Create a new skin for the TextInput control.
Figure 1. Create a new skin for the TextInput control.
Create SearchInputSkin as a copy of the default TextInputSkin.
Figure 2. Create SearchInputSkin as a copy of the default TextInputSkin.

In FlexWebTestDrive.mxml, switch to Source mode and look at the TextInput tag. It now has  a skinClass style set to the name of the new skin SearchInputSkin—which currently is the same as the default skin.

<s:TextInput id="searchTxt" prompt="Last Name" skinClass="skins.SearchInputSkin" .../>

Step 2: Set the skinClass in the style sheet.

Switch back to Design mode and with the TextInput selected, click Convert to CSS. In the New Style Rule dialog box, select Specific component with style name and name it searchInput (see Figure 3). Make this the style used by the search TextInput control in all the application states.

Create a class selector for TextInput controls.
Figure 3. Create a class selector for TextInput controls.

The new selector should appear as shown here:

s|TextInput.searchInput { skinClass: ClassReference("skins.SearchInputSkin"); }

This class selector can only be applied to TextInput controls.

Return to FlexWebTestDrive.mxml and note that styleName has only been set for one of the application states. To set it for all states, modify the source code or select the TextInput control and select Apply Current Properties to All States.

Note that instead of creating a class selector and applying it to the one TextInput instance as you did here, you could also have created and used an ID selector.

Step 3: Review the skin class.

Review the code for SearchInputSkin.mxml.

The skin class extends the SparkSkin base class and defines its host component, the component this skin can be applied to:

[HostComponent("spark.components.TextInput")]

In the Script block is some code to specify what subcomponents should be excluded when rendering a focus ring for the component.

Next, the skin states are defined:

<s:states> <s:State name="normal"/> <s:State name="disabled" stateGroups="disabledStates"/> <s:State name="normalWithPrompt"/> <s:State name="disabledWithPrompt" stateGroups="disabledStates"/> </s:states>

You can look up the names of the skin states the skin should contain in the component's API (see Figure 4). Remember you can open a component's API by selecting Help > Dynamic Help, clicking a tag in MXML, and then clicking the API link in the Help view.

Navigate to the TextInput skin states in the API.
Figure 4. Navigate to the TextInput skin states in the API.

Next are graphics tags that provide a way to define graphics with MXML tags (see Figure 5). There are multiple Rect tags, which draw rectangles for a border, fill, and shadow for TextInput controls that use this skin. The order in which the elements are defined defines their depth, so the fill rectangle is drawn on top of the border rectangle and the shadow rectangle on top of the fill rectangle.

Review the graphics code.
Figure 5. Review the graphics code.

At the end of the code are RichEditableText and Label controls. The RichEditableText control is the part of the TextInput component that holds and displays the input value. It is called a skin part and is a subcomponent of the TextInput control. The text property of the RichEditableText skin part gets set (in the TextInput component source code) to the text property of the TextInput control, which can be set programatically or by user input. The various attributes of the RichEditableText control specify where the RichEditableText should appear in the TextInput control; in this case, it is vertically aligned, with at least 1 pixel from the top, bottom, right, and left edges of the TextInput control. You modify these values to change where the RichEditableText control is displayed within the TextInput control.

<s:RichEditableText id="textDisplay" verticalAlign="middle" widthInChars="10" left="1" right="1" top="1" bottom="1" />

The Label control is the skin part of the TextInput component that holds and displays the optional prompt value. The  text property of the Label skin part is set (in the TextInput component source code) to the prompt property of the TextInput control. Just as for the RichEditableText skin part, you can set various attributes of the Label control to specify where the prompt Label should appear in the TextInput control.

<s:Label id="promptDisplay" maxDisplayedLines="1" verticalAlign="middle" mouseEnabled="false" mouseChildren="false" includeIn="normalWithPrompt,disabledWithPrompt" includeInLayout="false"/>

Note, the id values assigned to the two controls:textDisplay and promptDisplay. These are the names assigned to the subcomponents (the skin parts) defined and referenced in the host component's source code, in this case, the TextInput control. In order for you to specify the look and layout of the skin parts, you must use the id's assigned and used by the host component. You can look up the names and types of the skin parts you can reference in a component skin in the component's API (see Figure 6).

Navigate to the TextInput skin parts in the API.
Figure 6. Navigate to the TextInput skin parts in the API.

Step 4: Change the control's spacing.

In the SparkSkin tag, set minHeight to 30. In the RichEditableText tag, change the left, right, and top properties to 10 pixels and its bottom property to 7. Add these same values to the Label control and also set the includeInLayout property to true and set its fontStyle to normal.

Your code should appear as shown here:

<s:SparkSkin minHeight="30" ...> (...) <s:RichEditableText id="textDisplay" verticalAlign="middle" widthInChars="10" left="10" right="10" top="10" bottom="7" /> <s:Label id="promptDisplay" maxDisplayedLines="1" verticalAlign="middle" mouseEnabled="false" mouseChildren="false" includeIn="normalWithPrompt,disabledWithPrompt" includeInLayout="true" left="10" right="10" top="10" bottom="7" fontStyle="normal"/> </s:SparkSkin>

Step 5: Round the control's corners.

To each of the three Rect tags, add radiusX and radiusY properties set to 3 pixels.

Example code for one of the rectangles is shown here:

<s:Rect left="0" right="0" top="0" bottom="0" id="border" radiusX="3" radiusY="3"> <s:stroke> <s:SolidColorStroke id="borderStroke" weight="1" /> </s:stroke> </s:Rect>

Run the application and/or switch to Design mode for FlexWebTestDrive.mxml. The search TextInput control should now be larger, have rounded corners, and the prompt should no longer be italic (see Figure 7).

View the skinned TextInput control.
Figure 7. View the skinned TextInput control.

Next, skin the search button.

Step 6: Create a new Button skin file.

Return to Design mode of FlexWebTestDrive.mxml.Select the Search button and in the Properties view, click the button next to the Skin field and select Create Skin. In the New MXML Skin dialog box, create a skin called SearchButtonSkin in the skins package, leave the host component as spark.components.ButtonSkin, and uncheck Create as copy of (see Figure 8).

Create SearchButtonSkin.
Figure 8. Create SearchButtonSkin.

Step 7: Review the skin class.

In SearchButtonSkin.mxml, switch to Source mode and review the code.

The skin class extends the Skin base class and because you specified a host component in the dialog box to create it, the host component is also set:

[HostComponent("spark.components.Button")]

The skin states for a Button are also defined:

<s:states> <s:State name="disabled" /> <s:State name="down" /> <s:State name="over" /> <s:State name="up" /> </s:states>

Lastly, there is a comment listing the names and types of all the required and optional skin parts so you don’t have to look them up in the API (see Figure 9):

<!-- SkinParts name=iconDisplay, type=spark.primitives.BitmapImage, required=false name=labelDisplay, type=spark.core.IDisplayText, required=false -->
Look up the Button skin parts in the API.
Figure 9. Look up the Button skin parts in the API.

Step 8: Download the Test Drive assets.

Download and unzip testdrive_assets.zip and add search_icon.fxg to the FlextWebTestDrive project's assets folder. Open assets/search_icon.fxg and review the code (see Figure 10).

Add assets/search_icon.fxg to your project and review the code
Figure 10. Add assets/search_icon.fxg to your project and review the code

FXG is a declarative XML syntax for defining vector graphics that closely follows the Flash Player 10 rendering model. This FXG file was created by drawing in Fireworks and then selecting Commands > Export to FXG. You can also create FXG files using Illustrator or Photoshop.

In general, you should use an FXG file as a standalone component in your applications. This gives you the greatest amount of memory optimization, and lets you reuse your FXG files in other parts of the same application, or in other applications. In addition, by keeping the FXG file separate from the application, you can edit and export the FXG again from a graphics tool.

Although you can resize and animate the entire FXG component, you cannot modify objects within it at runtime. If you want to reference any of its subobjects, you need to convert the FXG syntax to MXML graphics and use those tags in your application instead.

Step 10: Add the graphics to the skin.

After the states in SearchButtonSkin.mxml, use Code Assist to select the search_icon FXG class (see Figure 11).

Add the search_icon FXG class.
Figure 11. Add the search_icon FXG class.

By using Code Assist, the namespace assignment was written for you in the Skin root tag: xmlns:assets="assets.*".

This tells the compiler where to find this class. You put the FXG file in the assets folder so  assets.* says look for files with the name of the tag in the assets folder.

Your skin class should appear as shown here:

<?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:assets="assets.*"> <fx:Metadata> [HostComponent("spark.components.Button")] </fx:Metadata> <s:states> <s:State name="disabled" /> <s:State name="down" /> <s:State name="over" /> <s:State name="up" /> </s:states> <assets:search_icon/> </s:Skin>

Save the file and then return to FlexWebTestDrive.mxml in Design mode. You should see the search button with the new skin (see Figure 12).

View the skinned search button.
Figure 12. View the skinned search button.

Step 11: Size and position the icon.

Return to SparkButtonSkin and set the minHeight and minWidth properties of the Skin class to 30. In the search_icon tag, set the horizontalCenter and verticalCenter properties to 0.

<s:Skin xmlns:assets="assets.*" minHeight="30" minWidth="30" ...> (...) <assets:search_icon horizontalCenter="0" verticalCenter="0"/>

Step 12: Add a background rectangle.

Above the search_icon tag, add a Rect tag and set its left, right, top, and bottom properties to 0. Set its topRightRadiusX, topRightRadiusY, bottomRightRadiusX, and bottomRightRadiusY properties to 3. Set its stroke property to an instance of the SolidColorStroke class with a color of #1A1A1A.

<s:Rect left="0" right="0" top="0" bottom="0" topRightRadiusX="3" topRightRadiusY="3" bottomRightRadiusX="3" bottomRightRadiusY="3"> <s:stroke> <s:SolidColorStroke color="#1A1A1A" weight="1"/> </s:stroke> </s:Rect>

The size of the rectangle is set by setting the left, right, top, and bottom properties to 0. The rectangle will fill the entire area of the button, leaving 0 pixels on each side.

The corner curvature is set by the radius properties. The corners on the right side will be rounded, the corners on the left side will be square (because no radii were specified).

The rectangle will be outlined with a solid dark line with a thickness of 1 pixel.

Step 13: Add a gradient fill.

Set the rectangle's fill property to an instance of the LinearGradient class with a rotation of 90. Add a GradientEntry with a color of 0x999999 and a color in the up state of 0x666666. Add a second GradientEntry with a color of 0x4D4D4D and a color in the up state of 0x333333.

<s:Rect left="0" right="0" top="0" bottom="0" topRightRadiusX="3" topRightRadiusY="3" bottomRightRadiusX="3" bottomRightRadiusY="3"> <s:stroke> <s:SolidColorStroke color="#1A1A1A" weight="1"/> </s:stroke> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0x999999" color.up="0x666666"/> <s:GradientEntry color="0x4D4D4D" color.up="0x333333"/> </s:LinearGradient> </s:fill> </s:Rect>

Save the file.

Step 14: Position the search controls.

Return to Design mode of FlexWebTestDrive.mxml and reposition the search TextInput and Button controls (see Figure 13). Make these the properties for all states.

Position the search controls.
Figure 13. Position the search controls.

To set the positions for all states, modify the source code or select each control and select Apply Current Properties to all Components.

Step 15: Set the skinClass in the style sheet.

With the Search button selected, click Convert to CSS. In the New Style Rule dialog box, select Specific component with style name and name it searchButton (see Figure 14). Return to Design mode of FlexWebTestDrive.mxml and make this the style for all states by right-clicking the search button and selecting Apply Current Properties to All States.

Create a searchButton class selector for Button controls.
Figure 14. Create a searchButton class selector for Button controls.

The new selector should appear as shown here:

s|Button.searchButton { skinClass: ClassReference("skins.SearchButtonSkin"); }

Run the application (see Figure 15). Enter a last name and click the search button; the controls should work exactly as before—they just have a new look.

Use the skinned search controls.
Figure 15. Use the skinned search controls.

You have now successfully skinned the TextInput and Button controls used to search the employees in the application.

In this tutorial, you learned to use skins to change the appearance of components.  You learned to create and modify a skin based on a default component skin and to create and add graphics to a new skin. In the next tutorial you skin the other controls in the application.

Learn more

Documentation: Using Flex 4.5

  • Spark Skinning
  • Skinning Spark components
  • MXML graphics
  • Graphics classes and elements
  • FXG
  • Using style properties in skins

ActionScript 3 Reference

  • spark.components
  • spark.primitives
  • mx.graphics

Flex Developer Center

  • UI design and RIA workflows
  • Flash Catalyst Developer Center

Documentation: Using Fireworks

  • Prototyping Flex applications
  • Export FXG files

Documentation: Using Illustrator

  • Working with FXG

Documentation: Using Photoshop

  • Photoshop CS5 FXG Extension

Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License+Adobe Commercial Rights

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

More Like This

  • Flex Test Drive: Build an application in an hour
  • Flex Test Drive: Change the appearance of your application
  • Flex Test Drive: Test and debug your code
  • Flex Test Drive: Modify the database
  • Flex Test Drive: Test and debug your code
  • Flex Test Drive: Modify the database
  • Flex Test Drive: Build an application in an hour
  • Flex Test Drive: Build an application in an hour
  • Flex Test Drive: Add charts and graphs
  • Flex Test Drive: Change the appearance of your application

Tutorials and 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