Customize the Spark TextInput Component in Flex 4 (Gumbo). Adding focus and Transitions.
Keywords: component, customizing, effects, FXG, skinning, SkinState, Spark, Transition
Changing the look of a spark component mainly comes down to customizing the skin-class, but there are situations where this might not be enough.
In a project I’m working on, we wanted to have a smooth transition when a text-input gets or loses focus. The default Spark TextInput and the associated skin-class do not have a focused state. (In Flex the FocusManager manages the focus by drawing a border around a component, but we wanted the focus on the skin itself and a transition)
One way to achieve this is to enhance the TextInput Component:
1.) Extend spark.components.TextInput
2.) Declare the additional SkinStates
public class AHTextInput extends TextInput { //Declare the additional SkinStates [SkinState("focused")]; private var bfocused:Boolean; public function AHTextInput() { super(); } ...
3.) Add Event-Listeners for the Focus-Event
//Add Event-Listeners to the textview for FocusEvent override protected function partAdded(partName:String, instance:Object):void { super.partAdded(partName, instance); if (instance == this.textView) { trace ("Adding TextView"); this.textView.addEventListener(FocusEvent.FOCUS_IN, onFocusInHandler); this.textView.addEventListener(FocusEvent.FOCUS_OUT, onFocusOutHandler); } } //Clean up Event-Listeners and stuff... override protected function partRemoved(partName:String, instance:Object):void { super.partRemoved(partName, instance); if (instance == this.textView) { this.textView.removeEventListener(FocusEvent.FOCUS_IN, onFocusInHandler); this.textView.removeEventListener(FocusEvent.FOCUS_OUT, onFocusOutHandler); } } ...
4.) Keep track of the state and leverage focused=false|true
//Handler for FocusIn Event private function onFocusInHandler(event:FocusEvent):void { bfocused = true; invalidateSkinState(); trace("Getting focus"); } //Handler for FocusOut private function onFocusOutHandler(event:FocusEvent):void { bfocused = false; invalidateSkinState(); trace("Loosing focus"); } //Gets called after invalidateSkinState() by Flex override protected function getCurrentSkinState():String { if (bfocused) { return "focused"; } else { return super.getCurrentSkinState(); } } ...
5.) Create a new Skin-Class which uses the additional states
<s:states> <s:State name="normal"/> <s:State name="disabled"/> <s:State name="focused"/> </s:states> <!-- background --> <s:Rect blendMode="normal" left="1" right="1" top="1" bottom="1" radiusX="3" radiusY="3" alpha="1"> <s:fill> <s:SolidColor id="bgFill" color="0xa2d2ff" color.focused="0xe8f8ff" /> </s:fill> <s:stroke> <s:SolidColorStroke id="stroke" color="0x92c2ef" color.focused="0xffffff" weight="1" /> </s:stroke> </s:Rect> ...
6.) Declare the transition inside the Skin-Class on the Elements you want
<!-- Transition from normal state to focused state and back --> <s:transitions> <s:Transition fromState="normal" toState="focused" > <s:AnimateColor duration="350" targets="{[bgFill, stroke]}" /> </s:Transition> <s:Transition fromState="focused" toState="normal" > <s:AnimateColor duration="350" targets="{[bgFill, stroke]}" /> </s:Transition> </s:transitions> ...
Test and source (sdk 4.0.0.7282). Note: textView has been renamed to textDisplay in the SkinnableTextBase.
Similar Posts
Custom Component in Flex 4 (Gumbo). A Knob Button - part 1.
Spark Icon Button with Gradient effects and Filter animation, colorized by styles. Flex 4 (Gumbo)
Sound in Flash 10 (beta). Generating Waveforms, Timbre and Pitch.
Custom PopUp Rating Component in Spark Flex 4 (Gumbo)
Skinning and creating custom rating component in flex 4 (Gumbo)


August 14th, 2009 at 2:52 pm
Hi There,
I’m trying your component (on flex 4.0.0.9237) and get this error message:
‘1119: Access of possibly undefined property textView through a reference with static type AHTextInput. AHTextInput.as TestWeb/src line 29 Flex Problem’
can you help me with this?
August 14th, 2009 at 3:39 pm
Lior,
Seems there’s been some renaming in the Flex SDK again.
Try using textDisplay in place of textView. Do this in the skin also, so that the skinPart is found.
hth
andy
August 14th, 2009 at 3:51 pm
working great!
thanks a lot
December 7th, 2009 at 2:51 pm
Good work in Flex textInput control.
Thanks for the useful code.
February 21st, 2010 at 3:38 pm
Andy,
Thank very much for the code!
Everything works great, but when the text begins to overflow, the control wraps its text inside (which looks ugly).
I recommend you to modify your partAdded method like this:
//Add Event-Listeners to the textview for FocusEvent
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
if (instance == this.textView) {
trace (”Adding TextView”);
this.textView.addEventListener(FocusEvent.FOCUS_IN, onFocusInHandler);
this.textView.addEventListener(FocusEvent.FOCUS_OUT, onFocusOutHandler);
// Prevent multiline
textDisplay.multiline = false;
// Single line for interactive input. Multi-line text can be set.
textDisplay.setStyle(”lineBreak”, “explicit”);
// TextInput should always be 1 line.
textDisplay.heightInLines = 1;
}
}
I added 3 lines from the FlexSDK source code of TextInput class.
Thanks again!
Roman
March 2nd, 2010 at 6:56 pm
Roman,
Thanks for your contribution.