Round cornered TextInput – Spark SDK
Just ran into this problem to create a rounded corner textbox for my flex application Flex 4 Spark SDK. I found there is no option for cornerRadius, i tried many ways to achieve that, finally i just created a custom skin based on the default TextInputSkin and applied that skin to the TextInput skinClass.
Here's the code snippet for RoundedTextInputSkin.
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
alpha.disabled="0.5"
blendMode="normal">
<fx:Metadata>
<![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.TextInput")]
]]>
</fx:Metadata>
<fx:Script>
private var paddingChanged:Boolean;
/* Define the skin elements that should not be colorized. */
static private const exclusions:Array=["background", "textDisplay"];
/**
* @copy spark.skins.SparkSkin#colorizeExclusions
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}
/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
static private const contentFill:Array=["bgFill"];
/**
* @inheritDoc
*/
override public function get contentItems():Array
{
return contentFill
}
;
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (paddingChanged)
{
updatePadding();
paddingChanged=false;
}
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle("borderVisible") == true)
{
border.visible=true;
shadow.visible=true;
background.left=background.top=background.right=background.bottom=2;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
}
else
{
border.visible=false;
shadow.visible=false;
background.left=background.top=background.right=background.bottom=0;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
/**
* @private
*/
private function updatePadding():void
{
if (!textDisplay)
return;
// Push padding styles into the textDisplay
var padding:Number;
padding=getStyle("paddingLeft");
if (textDisplay.getStyle("paddingLeft") != padding)
textDisplay.setStyle("paddingLeft", padding);
padding=getStyle("paddingTop");
if (textDisplay.getStyle("paddingTop") != padding)
textDisplay.setStyle("paddingTop", padding);
padding=getStyle("paddingRight");
if (textDisplay.getStyle("paddingRight") != padding)
textDisplay.setStyle("paddingRight", padding);
padding=getStyle("paddingBottom");
if (textDisplay.getStyle("paddingBottom") != padding)
textDisplay.setStyle("paddingBottom", padding);
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
if (!styleProp || styleProp.indexOf("padding") == 0)
{
paddingChanged=true;
invalidateProperties();
}
}
/**
* @inheritDoc
*/
override public function get focusSkinExclusions():Array
{
return [textDisplay]
}
;
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
</s:states>
<!-- border -->
<s:Rect left="0"
right="0"
top="0"
bottom="0"
id="border"
radiusX="10">
<s:stroke>
<s:SolidColorStroke color="{getStyle('borderColor')}"
alpha="{getStyle('borderAlpha')}"
weight="2"/>
</s:stroke>
</s:Rect>
<!-- fill -->
<!--- Defines the appearance of the TextInput component's background. -->
<s:Rect id="background"
left="1"
right="1"
top="1"
bottom="1"
radiusX="10">
<s:fill>
<!--- Defines the background fill color. -->
<s:SolidColor id="bgFill"
color="0xFFFFFF"/>
</s:fill>
</s:Rect>
<!-- text -->
<s:RichEditableText id="textDisplay"
lineBreak="explicit"
verticalAlign="middle"
widthInChars="10"
left="1"
right="1"
top="1"
bottom="1"/>
</s:SparkSkin>
xmlns:s="library://ns.adobe.com/flex/spark"
alpha.disabled="0.5"
blendMode="normal">
<fx:Metadata>
<![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.TextInput")]
]]>
</fx:Metadata>
<fx:Script>
private var paddingChanged:Boolean;
/* Define the skin elements that should not be colorized. */
static private const exclusions:Array=["background", "textDisplay"];
/**
* @copy spark.skins.SparkSkin#colorizeExclusions
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}
/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
static private const contentFill:Array=["bgFill"];
/**
* @inheritDoc
*/
override public function get contentItems():Array
{
return contentFill
}
;
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (paddingChanged)
{
updatePadding();
paddingChanged=false;
}
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle("borderVisible") == true)
{
border.visible=true;
shadow.visible=true;
background.left=background.top=background.right=background.bottom=2;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
}
else
{
border.visible=false;
shadow.visible=false;
background.left=background.top=background.right=background.bottom=0;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
/**
* @private
*/
private function updatePadding():void
{
if (!textDisplay)
return;
// Push padding styles into the textDisplay
var padding:Number;
padding=getStyle("paddingLeft");
if (textDisplay.getStyle("paddingLeft") != padding)
textDisplay.setStyle("paddingLeft", padding);
padding=getStyle("paddingTop");
if (textDisplay.getStyle("paddingTop") != padding)
textDisplay.setStyle("paddingTop", padding);
padding=getStyle("paddingRight");
if (textDisplay.getStyle("paddingRight") != padding)
textDisplay.setStyle("paddingRight", padding);
padding=getStyle("paddingBottom");
if (textDisplay.getStyle("paddingBottom") != padding)
textDisplay.setStyle("paddingBottom", padding);
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
if (!styleProp || styleProp.indexOf("padding") == 0)
{
paddingChanged=true;
invalidateProperties();
}
}
/**
* @inheritDoc
*/
override public function get focusSkinExclusions():Array
{
return [textDisplay]
}
;
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
</s:states>
<!-- border -->
<s:Rect left="0"
right="0"
top="0"
bottom="0"
id="border"
radiusX="10">
<s:stroke>
<s:SolidColorStroke color="{getStyle('borderColor')}"
alpha="{getStyle('borderAlpha')}"
weight="2"/>
</s:stroke>
</s:Rect>
<!-- fill -->
<!--- Defines the appearance of the TextInput component's background. -->
<s:Rect id="background"
left="1"
right="1"
top="1"
bottom="1"
radiusX="10">
<s:fill>
<!--- Defines the background fill color. -->
<s:SolidColor id="bgFill"
color="0xFFFFFF"/>
</s:fill>
</s:Rect>
<!-- shadow -->
<s:Rect left="1"
top="1"
right="1"
height="1"
id="shadow">
<s:fill>
<s:SolidColor color="0x000000"
alpha="0"/>
</s:fill>
</s:Rect>
<!-- text -->
<s:RichEditableText id="textDisplay"
lineBreak="explicit"
verticalAlign="middle"
widthInChars="10"
left="1"
right="1"
top="1"
bottom="1"/>
</s:SparkSkin>



This is perfect thanks! I think it is lame that adobe threw this away. I thought spark components were supposed to be better.
Hi KBala,
when I use the skin I get the error message “Required skin part popUp cannot be found”. I didn’t learn about skin parts yet, so I don’t have a clue about it. It seems the skin cannot be used generically. I’m using Flex 4 with Air 2.
Thanks, Thilo
Yeah, This skin only work with TextInput control.
I love you, ive been tryin to do this all day.
Works well! thanks a lot for sharing.
Regards
Hi Bala,
Thanks for sharing the code. Though I have a question for you. I see a lot of duplicated code from TextInputSkin from the Spark SDK.
Can we not extend the basic TextInputSkin from our custom skin class (RoundedTextInputSkin) and implement only those methods which are needed for the new functionality ??
Thanks,
Agraj
We can extend that, but need to write lot code to form the rounded corner. Good if you try that and let me know.
When i use the skin i am getting the error
“shadow” should be initialized.
This shadow is being used in updateDisplayList method.
I am 4.1.0 sdk.
I had the same issue as ilikeflex.
I fixed by adding a shadow (note I tweaked this for a text box with a radiusX of 8).
Grrr… hate comments that don’t recognize code
Lemme try again;
<!– SHADOW –>
<s:Rect left=”5″ top=”0″ right=”5″ height=”1″id=”shadow1″>
<s:fill>
<s:SolidColor color=”0×000000″ alpha=”0.3″ />
</s:fill>
</s:Rect>
<s:Rect left=”2″ top=”1″ right=”2″ height=”2″ id=”shadow2″>
<s:fill>
<s:SolidColor color=”0×000000″ alpha=”0.15″ />
</s:fill>
</s:Rect>
<s:Rect left=”0″ top=”3″ right=”0″ height=”1″ id=”shadow3″>
<s:fill>
<s:SolidColor color=”0×000000″ alpha=”0.08″ />
</s:fill>
</s:Rect>
Thanks.This was exactly what i wanted.
I cherished up to you’ll obtain carried out right here. The comic strip is attractive, your authored material stylish. nonetheless, you command get got an shakiness over that you want be handing over the following. ill definitely come further until now again since exactly the similar nearly very often inside case you protect this hike. edu backlinks
Thanks for spending the time to discuss this, I feel strongly about it and love studying more on this topic. If possible, as you change into an expert, would you mind updating your blog with more details?
Hi ,
I wanted to make the textinput show a magnifying glass image on the left side of the screen.(just like that in any browser)
but i cannot do so .
Can you please help me with it.
Hi ,
I wanted to make the text=-input show a magnifying glass image on the left side of the screen.(just like that in any browser)
but i cannot do so .
Can you please help me with it.
Can someone please help me with creating a custom skin without any border and have background color of my own.
Thanks in advance.
Thnx for the code….but wen i used this for text input it shows the two states are missing that is…. normalWithPrompt and disabledWithPrompt. so i just added these two states and declared it.. so i finally got the output…. i was happy with that output…. here is the code that i had done….
private var paddingChanged:Boolean;
/* Define the skin elements that should not be colorized. */
static private const exclusions:Array=["background", "textDisplay"];
/**
* @copy spark.skins.SparkSkin#colorizeExclusions
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}
/* Define the content fill items that should be colored by the “contentBackgroundColor” style. */
static private const contentFill:Array=["bgFill"];
/**
* @inheritDoc
*/
override public function get contentItems():Array
{
return contentFill
}
;
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (paddingChanged)
{
updatePadding();
paddingChanged=false;
}
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle(“borderVisible”) == true)
{
border.visible=true;
//shadow.visible=true;
background.left=background.top=background.right=background.bottom=2;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
}
else
{
border.visible=false;
//shadow.visible=false;
background.left=background.top=background.right=background.bottom=0;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
/**
* @private
*/
private function updatePadding():void
{
if (!textDisplay)
return;
// Push padding styles into the textDisplay
var padding:Number;
padding=getStyle(“paddingLeft”);
if (textDisplay.getStyle(“paddingLeft”) != padding)
textDisplay.setStyle(“paddingLeft”, padding);
padding=getStyle(“paddingTop”);
if (textDisplay.getStyle(“paddingTop”) != padding)
textDisplay.setStyle(“paddingTop”, padding);
padding=getStyle(“paddingRight”);
if (textDisplay.getStyle(“paddingRight”) != padding)
textDisplay.setStyle(“paddingRight”, padding);
padding=getStyle(“paddingBottom”);
if (textDisplay.getStyle(“paddingBottom”) != padding)
textDisplay.setStyle(“paddingBottom”, padding);
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
if (!styleProp || styleProp.indexOf(“padding”) == 0)
{
paddingChanged=true;
invalidateProperties();
}
}
/**
* @inheritDoc
*/
override public function get focusSkinExclusions():Array
{
return [textDisplay]
}
;
private var paddingChanged:Boolean;
/* Define the skin elements that should not be colorized. */
static private const exclusions:Array=["background", "textDisplay"];
/**
* @copy spark.skins.SparkSkin#colorizeExclusions
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}
/* Define the content fill items that should be colored by the “contentBackgroundColor” style. */
static private const contentFill:Array=["bgFill"];
/**
* @inheritDoc
*/
override public function get contentItems():Array
{
return contentFill
}
;
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (paddingChanged)
{
updatePadding();
paddingChanged=false;
}
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle(“borderVisible”) == true)
{
border.visible=true;
//shadow.visible=true;
background.left=background.top=background.right=background.bottom=2;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
}
else
{
border.visible=false;
//shadow.visible=false;
background.left=background.top=background.right=background.bottom=0;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
/**
* @private
*/
private function updatePadding():void
{
if (!textDisplay)
return;
// Push padding styles into the textDisplay
var padding:Number;
padding=getStyle(“paddingLeft”);
if (textDisplay.getStyle(“paddingLeft”) != padding)
textDisplay.setStyle(“paddingLeft”, padding);
padding=getStyle(“paddingTop”);
if (textDisplay.getStyle(“paddingTop”) != padding)
textDisplay.setStyle(“paddingTop”, padding);
padding=getStyle(“paddingRight”);
if (textDisplay.getStyle(“paddingRight”) != padding)
textDisplay.setStyle(“paddingRight”, padding);
padding=getStyle(“paddingBottom”);
if (textDisplay.getStyle(“paddingBottom”) != padding)
textDisplay.setStyle(“paddingBottom”, padding);
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
if (!styleProp || styleProp.indexOf(“padding”) == 0)
{
paddingChanged=true;
invalidateProperties();
}
}
/**
* @inheritDoc
*/
override public function get focusSkinExclusions():Array
{
return [textDisplay]
}
;
Just what I was looking for..
Thanks!