Auto resizable spark TextArea (Flex 4).

Creating auto resizable components is a typical and often not a hard task for developer. But there are some problems with TextArea. TextArea automatically displays scrollers when content is too large. The main suggestion in the internet on how to fix it is to add handlers on textChange event and resize TextArea by number of text lines. But it requires manual work every time you use TextArea, so this approach is not optimal. But there is a way to reskin TextArea to obtain autoresize, this way you’ll just need to apply this skin instead of default (or inherit from TextArea and make this new skin default).

The main skin part of TextArea is textDisplay. TextDisplay implements IEditableText and usually it is an instance of RichEditableText Class. RichEditableText has no scrolls and it determines its size by content. So the answer on how to create auto resizable TextArea you can find in skinClass. Let’s look default skin of TextArea from wireframe theme:

DefaultTextAreaSkin.mxml:

1.	<?xml version="1.0" encoding="utf-8"?>
2.	 
3.	<!--
4.	
5.	    ADOBE SYSTEMS INCORPORATED
6.	    Copyright 2008 Adobe Systems Incorporated
7.	    All Rights Reserved.
8.	
9.	    NOTICE: Adobe permits you to use, modify, and distribute this file
10.	    in accordance with the terms of the license agreement accompanying it.
11.	
12.	-->
13.	 
14.	<!--- The default wireframe skin class for the Spark TextArea component.
15.	        Skin classes in the wireframe package are useful for using as a simple base for a custom skin.
16.	        
17.	     @see spark.components.TextArea
18.	
19.	     @langversion 3.0
20.	     @playerversion Flash 10
21.	     @playerversion AIR 1.5
22.	     @productversion Flex 4
23.	-->
24.	<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
25.	     alpha.disabledStates="0.5">
26.	 
27.	    <fx:Metadata>
28.	        /**
29.	         * @copy spark.skins.spark.ApplicationSkin#hostComponent
30.	         */
31.	        [HostComponent("spark.components.TextArea")]
32.	    </fx:Metadata>
33.	    
34.	    <fx:Script>
35.	        <![CDATA[
36.	            /**
37.	             * @private
38.	             */
39.	            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
40.	            {
41.	                if (promptDisplay)
42.	                {
43.	                    promptDisplay.setLayoutBoundsSize(unscaledWidth - 1, unscaledHeight - 1);
44.	                    promptDisplay.setLayoutBoundsPosition(1, 1);
45.	                }
46.	                
47.	                super.updateDisplayList(unscaledWidth, unscaledHeight);
48.	            }            
49.	        ]]>
50.	    </fx:Script>
51.	 
52.	    <s:states>
53.	        <s:State name="normal"/>
54.	        <s:State name="disabled" stateGroups="disabledStates"/>
55.	        <s:State name="normalWithPrompt"/>
56.	        <s:State name="disabledWithPrompt" stateGroups="disabledStates"/>
57.	    </s:states>
58.	    
59.	    <!-- border/fill -->
60.	    <s:Rect left="0" right="0" top="0" bottom="0">
61.	        <s:stroke>
62.	            <s:SolidColorStroke color="#5C5C5C" weight="1"/>            
63.	        </s:stroke>
64.	        <s:fill>
65.	            <s:SolidColor color="#FFFFFF"/>
66.	        </s:fill>
67.	    </s:Rect>
68.	 
69.	    <!-- shadow -->
70.	    <s:Rect left="1" top="1" right="1" height="1">
71.	        <s:fill>
72.	            <s:SolidColor color="#000000" alpha="0.12" />
73.	        </s:fill>
74.	    </s:Rect>
75.	 
76.	    <!--- Defines the scroller used to scroll the TextArea. -->
77.	    <s:Scroller id="scroller" left="0" top="0" right="0" bottom="0" minViewportInset="1" measuredSizeIncludesScrollBars="false">
78.	        <!--- @copy spark.components.supportClasses.SkinnableTextBase#textDisplay -->
79.	        <s:RichEditableText id="textDisplay"
80.	                 heightInLines="10"
81.	                 widthInChars="15"
82.	                 paddingLeft="3" paddingTop="5"
83.	                 paddingRight="3" paddingBottom="3"/>
84.	    </s:Scroller>
85.	    <!--- Defines the Label that is used for prompt text. The includeInLayout property is false so the prompt text does not affect measurement. -->
86.	    <s:Label id="promptDisplay"
87.	             mouseEnabled="false" mouseChildren="false"
88.	             includeIn="normalWithPrompt,disabledWithPrompt"
89.	             includeInLayout="false"
90.	             paddingLeft="3" paddingTop="5"
91.	             paddingRight="3" paddingBottom="3"
92.	             />                
93.	 
94.	</s:Skin>

In the 79th line there is a textDisplay definition. As you see it is the child of Scroller. To make a resizable TextArea you’ll need to:

  1. Remove scrollers from the skin;
  2. Set heightInLines=”NaN” or remove property definition from mxml (textDisplay will determine its height automatically);
  3. Set widhtInChars=”NaN” or remove property (textDisplay will determine its width automatically);
  4. Set minHeight, left, top, right properties;
  5. If you use spark theme remove definition of textDisplay.bottom property from updateDisplayList and in mxml;

Completed skin for auto resizable TextArea (based on wireframe theme):

TextAreaWithNoScrollsSkin.mxml:

1.	<?xml version="1.0" encoding="utf-8"?>
2.	<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
3.	     alpha.disabledStates="0.5" minHeight="0">
4.	    <fx:Metadata>
5.	        [HostComponent("spark.components.TextArea")]
6.	    </fx:Metadata>
7.	    <fx:Script>
8.	        <![CDATA[
9.	            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
10.	            {
11.	                if (promptDisplay)
12.	                {
13.	                    promptDisplay.setLayoutBoundsSize(unscaledWidth - 1, unscaledHeight - 1);
14.	                    promptDisplay.setLayoutBoundsPosition(1, 1);
15.	                }
16.	                super.updateDisplayList(unscaledWidth, unscaledHeight);
17.	            }            
18.	        ]]>
19.	    </fx:Script>
20.	    <s:states>
21.	        <s:State name="normal"/>
22.	        <s:State name="disabled" stateGroups="disabledStates"/>
23.	        <s:State name="normalWithPrompt"/>
24.	        <s:State name="disabledWithPrompt" stateGroups="disabledStates"/>
25.	    </s:states>
26.	    
27.	    <s:Rect left="0" right="0" top="0" bottom="0">
28.	        <s:stroke>
29.	            <s:SolidColorStroke color="#5C5C5C" weight="1"/>            
30.	        </s:stroke>
31.	        <s:fill>
32.	            <s:SolidColor color="#FFFFFF"/>
33.	        </s:fill>
34.	    </s:Rect>
35.	 
36.	    <s:Rect left="1" top="1" right="1" height="1">
37.	        <s:fill>
38.	            <s:SolidColor color="#000000" alpha="0.12" />
39.	        </s:fill>
40.	    </s:Rect>
41.	 
42.	     <s:RichEditableText id="textDisplay" minHeight="0"
43.	                 left="5" right="5" top="5" paddingBottom="5"
44.	                 />
45.	    <s:Label id="promptDisplay"
46.	             mouseEnabled="false" mouseChildren="false"
47.	             includeIn="normalWithPrompt,disabledWithPrompt"
48.	             includeInLayout="false"
49.	             paddingLeft="3" paddingTop="5"
50.	             paddingRight="3" paddingBottom="3"
51.	             />                
52.	 
53.	</s:Skin>

Example of Application:

Main.mxml:

1.	<?xml version="1.0" encoding="utf-8"?>
2.	<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
3.	              xmlns:s="library://ns.adobe.com/flex/spark"
4.	              xmlns:mx="library://ns.adobe.com/flex/mx"
5.	              width="400" minHeight="600"
6.	              backgroundColor="#E6E6E6">
7.	    <fx:Declarations>
8.	    </fx:Declarations>
9.	    <s:layout>
10.	        <s:VerticalLayout paddingTop="40" paddingLeft="10" paddingRight="10"/>
11.	    </s:layout>
12.	    <s:TextArea skinClass="com.yumasoft.skins.TextAreaNoScrollsSkin" maxWidth="300"/>
13.	    <s:TextArea width="100%" skinClass="com.yumasoft.skins.TextAreaNoScrollsSkin"/>
14.	</s:Application>

Example:

Screenshot:
screenshot.png

AttachmentSize
Full source code25.83 KB
Auto resizeable TextAreas skin with spark theme1.77 KB
Auto resizeable TextAreas skin with wireframe theme856 bytes