Customize the Spark TextInput Component in Flex 4 (Gumbo). Adding focus and Transitions.

June 1, 2009. Posted by Andy Hulstkamp under Actionscript 3 FXG Flash Gumbo (Flex 4 beta) Misc Sound
Keywords: , , , , , , ,

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)

custom TextInput

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.



Share/Save/Bookmark

6 Responses to “Customize the Spark TextInput Component in Flex 4 (Gumbo). Adding focus and Transitions.”

  1. Lior Says:

    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?

  2. Andy Hulstkamp Says:

    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

  3. Lior Says:

    working great!

    thanks a lot :-)

  4. prasad Says:

    Good work in Flex textInput control.

    Thanks for the useful code.

  5. Roman Shumikhin Says:

    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

  6. Andy Hulstkamp Says:

    Roman,

    Thanks for your contribution.

Leave a Reply