http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/SpinnerListSkin.as
----------------------------------------------------------------------
diff --git a/tourdeflexmobile/src/spark/skins/android4/SpinnerListSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/SpinnerListSkin.as
new file mode 100644
index 0000000..006fddb
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/SpinnerListSkin.as
@@ -0,0 +1,293 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package spark.skins.android4
+{
+       import flash.display.InteractiveObject;
+       
+       import mx.core.ClassFactory;
+       import mx.core.DPIClassification;
+       import mx.core.mx_internal;
+       
+       import spark.components.DataGroup;
+       import spark.components.Scroller;
+       import spark.components.SpinnerList;
+       import spark.components.SpinnerListItemRenderer;
+       import spark.layouts.VerticalSpinnerLayout;
+       import 
spark.skins.android4.assets.SpinnerListContainerSelectionIndicator;
+       import spark.skins.mobile.supportClasses.MobileSkin;    
+       
+       
+       use namespace mx_internal;
+       /**
+        *  ActionScript-based skin for the SpinnerList in mobile applications. 
+        * 
+        *  @see spark.components.SpinnerList
+        * 
+        *  @langversion 3.0
+        *  @playerversion AIR 3
+        *  @productversion Flex 4.6
+        */
+       public class SpinnerListSkin extends MobileSkin
+       {
+               /**
+                *  Constructor.
+                * 
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */
+               public function SpinnerListSkin()
+               {
+                       super();
+                       
+                       selectionIndicatorClass = 
spark.skins.android4.assets.SpinnerListContainerSelectionIndicator;
+                       borderThickness = 1;
+                       switch (applicationDPI)
+                       {
+                               case DPIClassification.DPI_640:
+                               {
+                                       selectionIndicatorHeight = 182;
+                                       minWidth = 64;
+                                       borderThickness = 3;
+                                       break;
+                               }
+                               case DPIClassification.DPI_480:
+                               {
+                                       selectionIndicatorHeight = 144;
+                                       minWidth = 48;
+                                       borderThickness = 2;
+                                       break;
+                               }
+                               case DPIClassification.DPI_320:
+                               {
+                                       selectionIndicatorHeight = 96;
+                                       minWidth = 32;
+                                       borderThickness = 2;
+                                       break;
+                               }
+                               case DPIClassification.DPI_240:
+                               {
+                                       selectionIndicatorHeight = 72;
+                                       minWidth = 24;
+                                       borderThickness = 1;
+                                       break;
+                               }
+                               case DPIClassification.DPI_120:
+                               {
+                                       selectionIndicatorHeight = 36;
+                                       minWidth = 12;
+                                       borderThickness = 0;
+                                       break;
+                               }
+                               default:
+                               {
+                                       selectionIndicatorHeight = 48;
+                                       minWidth = 16;
+                                       borderThickness = 1;
+                               }   
+                       }
+                       
+               }
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Skin parts 
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  Scroller skin part.
+                *
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */ 
+               public var scroller:Scroller;
+               
+               /**
+                *  DataGroup skin part.
+                *
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */ 
+               public var dataGroup:DataGroup;
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Properties 
+               //
+               
//--------------------------------------------------------------------------
+               /** 
+                *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+                *
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */
+               public var hostComponent:SpinnerList;
+               
+               /**
+                *  Pixel size of the border.
+                *
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */ 
+               protected var borderThickness:int;
+               
+               /**
+                *  Class for the selection indicator skin part. 
+                *       
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */
+               protected var selectionIndicatorClass:Class;
+               
+               /**
+                *  Selection indicator skin part. 
+                *       
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */
+               protected var selectionIndicator:InteractiveObject;
+               
+               /**
+                *  Height of the selection indicator.  
+                *       
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */
+               protected var selectionIndicatorHeight:Number;
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Overridden Methods 
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  @private
+                */
+               override protected function commitCurrentState():void
+               {
+                       super.commitCurrentState();
+                       
+                       alpha = currentState.indexOf("disabled") == -1 ? 1 : 
0.5;
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function createChildren():void
+               {           
+                       super.createChildren();
+                       
+                       if (!dataGroup)
+                       {
+                               // Create data group layout
+                               var layout:VerticalSpinnerLayout = new 
VerticalSpinnerLayout();
+                               layout.requestedRowCount = 5;
+                               // Create data group
+                               dataGroup = new DataGroup();
+                               dataGroup.id = "dataGroup";
+                               dataGroup.layout = layout;
+                               
+                               dataGroup.itemRenderer = new 
ClassFactory(spark.components.SpinnerListItemRenderer);
+                       }
+                       
+                       if (!scroller)
+                       {
+                               // Create scroller
+                               scroller = new Scroller();
+                               scroller.id = "scroller";
+                               scroller.hasFocusableChildren = false;
+                               scroller.ensureElementIsVisibleForSoftKeyboard 
= false;
+                               // Only support vertical scrolling
+                               scroller.setStyle("verticalScrollPolicy","on");
+                               scroller.setStyle("horizontalScrollPolicy", 
"off");
+                               scroller.setStyle("skinClass", 
spark.skins.android4.SpinnerListScrollerSkin);
+                               
+                               addChild(scroller);
+                       }
+                       
+                       if (!selectionIndicator)
+                       {
+                               // Selection indicator is on top
+                               selectionIndicator = new 
selectionIndicatorClass();
+                               selectionIndicator.mouseEnabled = false;
+                               addChild(selectionIndicator);
+                       }
+                       
+                       // Associate scroller with data group
+                       if (!scroller.viewport)
+                               scroller.viewport = dataGroup;
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function measure():void
+               {
+                       measuredWidth = scroller.getPreferredBoundsWidth() + 
borderThickness * 2;
+                       measuredHeight = scroller.getPreferredBoundsHeight();
+                       //add in for selection indicator
+                       measuredMinHeight = selectionIndicatorHeight + 
borderThickness * 4;
+                       minHeight = measuredMinHeight;                  
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function 
layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+               {   
+                       super.layoutContents(unscaledWidth, unscaledHeight);    
                
+                       
+                       // Scroller
+                       setElementSize(scroller, unscaledWidth - 
borderThickness * 2, unscaledHeight);
+                       setElementPosition(scroller, borderThickness, 0);
+                       //selection indicator
+                       unscaledHeight = Math.max(unscaledHeight, 
selectionIndicatorHeight + borderThickness * 4);
+                       
+                       setElementSize(selectionIndicator, unscaledWidth, 
selectionIndicatorHeight);
+                       setElementPosition(selectionIndicator, 0, 
Math.floor((unscaledHeight - selectionIndicatorHeight) / 2));
+               }
+               
+               /**
+                *  @private
+                */
+               override public function styleChanged(styleProp:String):void
+               {
+                       // Reinitialize the typical element so it picks up the 
latest styles
+                       // Font styles might impact the size of the SpinnerList
+                       if (styleProp != "color" && styleProp != "accentColor")
+                       {
+                               if (dataGroup)
+                                       
dataGroup.invalidateTypicalItemRenderer();
+                       }
+                       
+                       super.styleChanged(styleProp);
+               }
+               
+       }
+}
+

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/SplitViewNavigatorSkin.as
----------------------------------------------------------------------
diff --git 
a/tourdeflexmobile/src/spark/skins/android4/SplitViewNavigatorSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/SplitViewNavigatorSkin.as
new file mode 100644
index 0000000..ee06eea
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/SplitViewNavigatorSkin.as
@@ -0,0 +1,157 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+       import mx.core.mx_internal;
+       
+       import spark.components.Callout;
+       import spark.components.Group;
+       import spark.components.SkinnablePopUpContainer;
+       import spark.components.SplitViewNavigator;
+       import spark.layouts.HorizontalLayout;
+       import spark.skins.mobile.supportClasses.MobileSkin;
+       
+       use namespace mx_internal;
+       
+       /**
+        *  The default skin for the SplitViewNavigator component.  This skin is
+        *  chromeless and doesn't draw a background, border or separator.  
+        *  It only contains a single content group with a horizontal layout to 
hold 
+        *  the navigators, and a Callout component.  
+        *  The Callout component uses the default values for its layout 
properties.
+        * 
+        *  @see spark.components.Callout
+        *  @see spark.components.SplitViewNavigator
+        * 
+        *  @langversion 3.0
+        *  @playerversion AIR 3
+        *  @productversion Flex 4.6
+        */
+       public class SplitViewNavigatorSkin extends MobileSkin
+       {
+               
//--------------------------------------------------------------------------
+               //
+               //  Constructor
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  Constructor.
+                * 
+                *  @langversion 3.0
+                *  @playerversion AIR 3
+                *  @productversion Flex 4.6
+                */
+               public function SplitViewNavigatorSkin()
+               {
+                       super();
+               }
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  SkinParts
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  @copy spark.components.SkinnableContainer#contentGroup
+                */
+               public var contentGroup:Group;
+               
+               /**
+                *  @copy spark.components.SplitViewNavigator#viewNavigatorPopUp
+                */ 
+               public var viewNavigatorPopUp:SkinnablePopUpContainer;
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Variables
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+                */
+               public var hostComponent:SplitViewNavigator;
+               
+               
//--------------------------------------------------------------------------
+               //
+               // Overridden Methods
+               //
+               
//--------------------------------------------------------------------------
+               /**
+                *  @private
+                */
+               override protected function createChildren():void
+               {
+                       // Create the layout for the content group
+                       var hLayout:HorizontalLayout = new HorizontalLayout();
+                       
+                       // A gap of 1 is used to reveal a thin line of the 
background between
+                       // each child navigator.  This serves as a divider.  To 
change the look
+                       // of the divider, change the backgroundColor style.
+                       hLayout.gap = 1;
+                       
+                       // Create the contentGroup
+                       contentGroup = new Group();
+                       contentGroup.id = "contentGroup";
+                       contentGroup.layout = hLayout;
+                       addChild(contentGroup);
+                       
+                       // Create the callout but don't add it to display list
+                       viewNavigatorPopUp = new Callout();
+                       viewNavigatorPopUp.id = "viewNavigatorPopUp";
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function measure():void
+               {
+                       super.measure();
+                       
+                       measuredWidth = contentGroup.getPreferredBoundsWidth();
+                       measuredHeight = 
contentGroup.getPreferredBoundsHeight();
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function 
layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+               {
+                       super.layoutContents(unscaledWidth, unscaledHeight);
+                       
+                       contentGroup.setLayoutBoundsSize(unscaledWidth, 
unscaledHeight);
+                       contentGroup.setLayoutBoundsPosition(0, 0);
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function 
drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+               {
+                       // Background is used to draw the divider between each 
navigator
+                       var color:uint = getStyle("backgroundColor");
+                       graphics.beginFill(color);
+                       graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
+                       graphics.endFill();
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/StageTextAreaSkin.as
----------------------------------------------------------------------
diff --git a/tourdeflexmobile/src/spark/skins/android4/StageTextAreaSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/StageTextAreaSkin.as
new file mode 100644
index 0000000..97daa08
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/StageTextAreaSkin.as
@@ -0,0 +1,185 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+import mx.utils.Platform;
+
+import spark.components.TextArea;
+import spark.components.supportClasses.StyleableTextField;
+import spark.skins.android4.supportClasses.StageTextSkinBase;
+
+use namespace mx_internal;
+
+/**
+ *  ActionScript-based skin for TextArea controls in mobile applications that 
uses a
+ *  StyleableStageText class for the text display. 
+ * 
+ *  @see spark.components.TextArea
+ *  @see spark.components.supportClasses.StyleableStageText
+ * 
+ *  @langversion 3.0
+ *  @playerversion AIR 3.0 
+ *  @productversion Flex 4.6
+ */
+public class StageTextAreaSkin extends StageTextSkinBase
+{
+    
//--------------------------------------------------------------------------
+    //
+    //  Class variables
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  The underlying native text control on iOS has internal margins of its
+     *  own. In order to remain faithful to the paddingTop and paddingBottom
+     *  style values that developers may specify, those internal margins need 
to
+     *  be compensated for. This variable contains size of that compensation in
+     *  pixels.
+     */
+    mx_internal static var iOSVerticalPaddingAdjustment:Number = 5;
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    
//--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3.0
+     *  @productversion Flex 4.6
+     */
+    public function StageTextAreaSkin()
+    {
+        super();
+        multiline = true;
+        
+        switch (applicationDPI)
+        {
+                       case DPIClassification.DPI_640:
+                       {
+                               measuredDefaultHeight = 212;
+                               break;
+                       }
+                       case DPIClassification.DPI_480:
+                       {
+                               measuredDefaultHeight = 140;
+                               break;
+                       }
+            case DPIClassification.DPI_320:
+            {
+                measuredDefaultHeight = 106;
+                break;
+            }
+                       case DPIClassification.DPI_240:
+                       {
+                               measuredDefaultHeight = 70;
+                               break;
+                       }
+                       case DPIClassification.DPI_120:
+                       {
+                               measuredDefaultHeight = 35;
+                               break;
+                       }
+            default:
+            {
+                measuredDefaultHeight = 48;
+                break;
+            }
+        }
+    }
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    
//--------------------------------------------------------------------------
+    
+    /** 
+     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:TextArea;  // SkinnableComponent will populate
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    
//--------------------------------------------------------------------------
+       
+
+       
+    /**
+     *  @private
+     */
+    override protected function layoutContents(unscaledWidth:Number,  
unscaledHeight:Number):void
+    {
+        // base class handles border position & size
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        // position & size the text
+        var paddingLeft:Number = getStyle("paddingLeft");
+        var paddingRight:Number = getStyle("paddingRight");
+        var paddingTop:Number = getStyle("paddingTop");
+        var paddingBottom:Number = getStyle("paddingBottom");
+        
+        var unscaledTextWidth:Number = Math.max(0, unscaledWidth - paddingLeft 
- paddingRight);
+        var unscaledTextHeight:Number = Math.max(0, unscaledHeight - 
paddingTop - paddingBottom);
+        
+        if (textDisplay)
+        {
+            var verticalPosAdjustment:Number = 0;
+            var heightAdjustment:Number = 0;
+            
+            if (Platform.isIOS)
+            {
+                verticalPosAdjustment = Math.min(iOSVerticalPaddingAdjustment, 
paddingTop);
+                heightAdjustment = verticalPosAdjustment + 
Math.min(iOSVerticalPaddingAdjustment, paddingBottom);
+            }
+            
+            textDisplay.commitStyles();
+            setElementSize(textDisplay, unscaledTextWidth, unscaledTextHeight 
+ heightAdjustment);
+            setElementPosition(textDisplay, paddingLeft, paddingTop - 
verticalPosAdjustment);
+        }
+        
+        if (promptDisplay)
+        {
+            if (promptDisplay is StyleableTextField)
+                StyleableTextField(promptDisplay).commitStyles();
+            
+            setElementSize(promptDisplay, unscaledTextWidth, 
unscaledTextHeight);
+            setElementPosition(promptDisplay, paddingLeft, paddingTop);
+        }
+    }
+
+       /**
+        *  @private
+        */
+       override protected function measure():void
+       {
+               super.measure();
+               measureTextComponent(hostComponent);
+       }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/StageTextInputSkin.as
----------------------------------------------------------------------
diff --git a/tourdeflexmobile/src/spark/skins/android4/StageTextInputSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/StageTextInputSkin.as
new file mode 100644
index 0000000..4bcc4d9
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/StageTextInputSkin.as
@@ -0,0 +1,130 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+import spark.components.TextInput;
+import spark.components.supportClasses.StyleableTextField;
+import spark.skins.android4.supportClasses.StageTextSkinBase;
+
+/**
+ *  ActionScript-based skin for TextInput controls in mobile applications that 
uses a
+ *  StyleableStageText class for the text input. 
+ * 
+ *  @see spark.components.TextInput
+ *  @see spark.components.supportClasses.StyleableStageText
+ * 
+ *  @langversion 3.0
+ *  @playerversion AIR 3.0 
+ *  @productversion Flex 4.6
+ */
+public class StageTextInputSkin extends StageTextSkinBase
+{
+    
//--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    
//--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion AIR 3.0
+     *  @productversion Flex 4.6
+     */
+    public function StageTextInputSkin()
+    {
+        super();
+        multiline = false;
+    }    
+
+    
//--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    
//--------------------------------------------------------------------------
+    
+    /** 
+     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:TextInput;  // SkinnableComponent will populate
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    
//--------------------------------------------------------------------------
+       
+       /**
+        *  @private
+        */     
+       override protected function measure():void
+       {
+               super.measure();
+               measureTextComponent(hostComponent);
+       }
+       
+    /**
+     *  @private
+     */
+    override protected function layoutContents(unscaledWidth:Number, 
+                                               unscaledHeight:Number):void
+    {
+        // base class handles border position & size
+        super.layoutContents(unscaledWidth, unscaledHeight);
+        
+        // position & size the text
+        var paddingLeft:Number = getStyle("paddingLeft");
+        var paddingRight:Number = getStyle("paddingRight");
+        var paddingTop:Number = getStyle("paddingTop");
+        var paddingBottom:Number = getStyle("paddingBottom");
+        
+        var unscaledTextWidth:Number = Math.max(0, unscaledWidth - paddingLeft 
- paddingRight);
+        var unscaledTextHeight:Number = Math.max(0, unscaledHeight - 
paddingTop - paddingBottom);
+        
+        // default vertical positioning is centered
+        var textHeight:Number = getElementPreferredHeight(textDisplay);
+        var textY:Number = Math.round(0.5 * (unscaledTextHeight - textHeight)) 
+ paddingTop;
+        
+        if (textDisplay)
+        {
+            textDisplay.commitStyles();
+            setElementSize(textDisplay, unscaledTextWidth, unscaledTextHeight);
+            setElementPosition(textDisplay, paddingLeft, textY);
+        }
+        
+        if (promptDisplay)
+        {
+            if (promptDisplay is StyleableTextField)
+                StyleableTextField(promptDisplay).commitStyles();
+            
+            var promptHeight:Number = getElementPreferredHeight(promptDisplay);
+            var promptY:Number = Math.round(0.5 * (unscaledTextHeight - 
promptHeight)) + paddingTop;
+                
+            setElementSize(promptDisplay, unscaledTextWidth, promptHeight);
+            setElementPosition(promptDisplay, paddingLeft, promptY);
+        }
+    }
+    
+    /**
+     *  @private
+     */
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/TabbedViewNavigatorTabBarSkin.as
----------------------------------------------------------------------
diff --git 
a/tourdeflexmobile/src/spark/skins/android4/TabbedViewNavigatorTabBarSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/TabbedViewNavigatorTabBarSkin.as
new file mode 100644
index 0000000..eea5948
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/TabbedViewNavigatorTabBarSkin.as
@@ -0,0 +1,122 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+import spark.components.ButtonBarButton;
+import spark.components.DataGroup;
+import spark.skins.mobile.supportClasses.ButtonBarButtonClassFactory;
+import 
spark.skins.mobile.supportClasses.TabbedViewNavigatorTabBarHorizontalLayout;
+
+/**
+ *  The Android 4.x specific skin class for the Spark TabbedViewNavigator 
tabBar skin part.
+ *  It uses the ButtonBarFirstButtonSkin and ButtonBarMiddleButtonSkin as 
skins for first
+ *  middle buttons
+ *  
+ *  @see spark.components.TabbedViewNavigator#tabBar
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5
+ *  @productversion Flex 4.5
+ */
+public class TabbedViewNavigatorTabBarSkin extends ButtonBarSkin
+{
+    
//--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    
//--------------------------------------------------------------------------
+    
+    /**
+     *  Constructor.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     * 
+     */
+    public function TabbedViewNavigatorTabBarSkin()
+    {
+        super();
+    }
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    
//--------------------------------------------------------------------------
+    
+    /**
+     *  @private
+     */
+    override protected function createChildren():void
+    {
+        if (!firstButton)
+        {
+            firstButton = new ButtonBarButtonClassFactory(ButtonBarButton);
+            firstButton.skinClass = 
spark.skins.android4.ButtonBarFirstButtonSkin;
+        }
+        
+        if (!lastButton)
+        {
+            lastButton = new ButtonBarButtonClassFactory(ButtonBarButton);
+            lastButton.skinClass = 
spark.skins.android4.ButtonBarFirstButtonSkin;
+        }
+        
+        if (!middleButton)
+        {
+            middleButton = new ButtonBarButtonClassFactory(ButtonBarButton);
+            middleButton.skinClass = 
spark.skins.android4.ButtonBarMiddleButtonSkin;
+        }
+        
+        if (!dataGroup)
+        {
+            // TabbedViewNavigatorButtonBarHorizontalLayout for even percent 
layout
+            var tabLayout:TabbedViewNavigatorTabBarHorizontalLayout = 
+                new TabbedViewNavigatorTabBarHorizontalLayout();
+            tabLayout.useVirtualLayout = false;
+            
+            dataGroup = new DataGroup();
+            dataGroup.layout = tabLayout;
+            addChild(dataGroup);
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    override protected function drawBackground(unscaledWidth:Number, 
unscaledHeight:Number):void
+    {
+        super.drawBackground(unscaledWidth, unscaledHeight);
+
+        // backgroundAlpha style is not supported by ButtonBar
+        // TabbedViewNavigatorSkin sets a hard-coded value to support
+        // overlayControls
+        var backgroundAlphaValue:* = getStyle("backgroundAlpha");
+        var backgroundAlpha:Number = (backgroundAlphaValue === undefined)
+            ? 1 : getStyle("backgroundAlpha");
+        
+        graphics.beginFill(getStyle("chromeColor"), backgroundAlpha);
+        graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
+        graphics.endFill();
+    }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarSkin.as
----------------------------------------------------------------------
diff --git 
a/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarSkin.as
new file mode 100644
index 0000000..540318e
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarSkin.as
@@ -0,0 +1,105 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package spark.skins.android4
+{
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+    /**
+     *  The default skin class for the Spark TextAreaHScrollBar component in 
mobile
+    *  applications.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+public class TextAreaHScrollBarSkin extends HScrollBarSkin
+{
+    /**
+     *  Constructor.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     */
+    public function TextAreaHScrollBarSkin()
+    {
+        super();
+
+        thumbSkinClass = TextAreaHScrollBarThumbSkin;
+        var paddingBottom:int;
+        var paddingHorizontal:int;
+
+        switch (applicationDPI)
+        {
+                       case DPIClassification.DPI_640:
+                       {
+                               minHeight = 30;
+                               paddingBottom = 
TextAreaHScrollBarThumbSkin.PADDING_BOTTOM_320DPI;
+                               paddingHorizontal = 
TextAreaHScrollBarThumbSkin.PADDING_HORIZONTAL_320DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_480:
+                       {
+                               minHeight = 22;
+                               paddingBottom = 
TextAreaHScrollBarThumbSkin.PADDING_BOTTOM_480DPI;
+                               paddingHorizontal = 
TextAreaHScrollBarThumbSkin.PADDING_HORIZONTAL_480DPI;
+                               break;
+                       }
+            case DPIClassification.DPI_320:
+            {
+                minHeight = 15;
+                paddingBottom = 
TextAreaHScrollBarThumbSkin.PADDING_BOTTOM_320DPI;
+                paddingHorizontal = 
TextAreaHScrollBarThumbSkin.PADDING_HORIZONTAL_320DPI;
+                break;
+            }
+                       case DPIClassification.DPI_240:
+                       {
+                               minHeight = 11;
+                               paddingBottom = 
TextAreaHScrollBarThumbSkin.PADDING_BOTTOM_240DPI;
+                               paddingHorizontal = 
TextAreaHScrollBarThumbSkin.PADDING_HORIZONTAL_240DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_120:
+                       {
+                               minHeight = 11;
+                               paddingBottom = 
TextAreaHScrollBarThumbSkin.PADDING_BOTTOM_120DPI;
+                               paddingHorizontal = 
TextAreaHScrollBarThumbSkin.PADDING_HORIZONTAL_120DPI;
+                               break;
+                       }
+            default:
+            {
+                // default DPI_160
+                minHeight = 9;
+                paddingBottom = 
TextAreaHScrollBarThumbSkin.PADDING_BOTTOM_DEFAULTDPI;
+                paddingHorizontal = 
TextAreaHScrollBarThumbSkin.PADDING_HORIZONTAL_DEFAULTDPI;
+                break;
+            }
+        }
+        
+        // The minimum width is set such that, at it's smallest size, the 
thumb appears
+        // as wide as it is high.
+        minThumbWidth = (minHeight - paddingBottom) + (paddingHorizontal * 2); 
  
+    }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarThumbSkin.as
----------------------------------------------------------------------
diff --git 
a/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarThumbSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarThumbSkin.as
new file mode 100644
index 0000000..5d3fec8
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/TextAreaHScrollBarThumbSkin.as
@@ -0,0 +1,116 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package spark.skins.android4
+{
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+/**
+ *  The ActionScript-based skin used for TextAreaHScrollBarThumb components
+ *  in mobile applications.
+ * 
+ *  @langversion 3.0
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ * 
+ */
+public class TextAreaHScrollBarThumbSkin extends HScrollBarThumbSkin
+{
+    
//--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    
//--------------------------------------------------------------------------
+    
+    // These constants are also accessed from HScrollBarSkin
+       mx_internal static const PADDING_BOTTOM_640DPI:int = 16;
+       mx_internal static const PADDING_HORIZONTAL_640DPI:int = 16;
+       mx_internal static const PADDING_BOTTOM_480DPI:int = 12;
+       mx_internal static const PADDING_HORIZONTAL_480DPI:int = 12;
+    mx_internal static const PADDING_BOTTOM_320DPI:int = 8;
+    mx_internal static const PADDING_HORIZONTAL_320DPI:int = 12;
+       mx_internal static const PADDING_BOTTOM_240DPI:int = 6;
+       mx_internal static const PADDING_HORIZONTAL_240DPI:int = 6;
+       mx_internal static const PADDING_BOTTOM_120DPI:int = 3;
+       mx_internal static const PADDING_HORIZONTAL_120DPI:int = 3;
+    mx_internal static const PADDING_BOTTOM_DEFAULTDPI:int = 4;
+    mx_internal static const PADDING_HORIZONTAL_DEFAULTDPI:int = 6;
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    
//--------------------------------------------------------------------------
+    /**
+     *  Constructor.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5
+     *  @productversion Flex 4.5
+     */
+    public function TextAreaHScrollBarThumbSkin()
+    {
+        super();
+        
+        // Depending on density set padding
+        switch (applicationDPI)
+        {
+                       case DPIClassification.DPI_640:
+                       {
+                               paddingBottom = PADDING_BOTTOM_640DPI;
+                               paddingHorizontal = PADDING_HORIZONTAL_640DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_480:
+                       {
+                               paddingBottom = 
TextAreaHScrollBarThumbSkin.PADDING_BOTTOM_480DPI;
+                               paddingHorizontal = 
TextAreaHScrollBarThumbSkin.PADDING_HORIZONTAL_480DPI;
+                               break;
+                       }
+            case DPIClassification.DPI_320:
+            {
+                paddingBottom = PADDING_BOTTOM_320DPI;
+                paddingHorizontal = PADDING_HORIZONTAL_320DPI;
+                break;
+            }
+                       case DPIClassification.DPI_240:
+                       {
+                               paddingBottom = PADDING_BOTTOM_240DPI;
+                               paddingHorizontal = PADDING_HORIZONTAL_240DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_120:
+                       {
+                               paddingBottom = PADDING_BOTTOM_120DPI;
+                               paddingHorizontal = PADDING_HORIZONTAL_120DPI;
+                               break;
+                       }
+            default:
+            {
+                paddingBottom = PADDING_BOTTOM_DEFAULTDPI;
+                paddingHorizontal = PADDING_HORIZONTAL_DEFAULTDPI;
+                break;
+            }
+        }
+    }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/TextAreaSkin.as
----------------------------------------------------------------------
diff --git a/tourdeflexmobile/src/spark/skins/android4/TextAreaSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/TextAreaSkin.as
new file mode 100644
index 0000000..6d1fa52
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/TextAreaSkin.as
@@ -0,0 +1,892 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.skins.android4
+{
+       
+       import flash.events.Event;
+       import flash.events.FocusEvent;
+       import flash.events.KeyboardEvent;
+       import flash.events.MouseEvent;
+       import flash.events.SoftKeyboardEvent;
+       import flash.geom.Point;
+       import flash.geom.Rectangle;
+       import flash.system.Capabilities;
+       import flash.text.TextLineMetrics;
+       import flash.ui.Keyboard;
+       
+       import mx.core.DPIClassification;
+       import mx.core.EventPriority;
+       import mx.core.FlexGlobals;
+       import mx.core.mx_internal;
+       import mx.events.FlexEvent;
+       import mx.utils.Platform;
+       
+       import spark.components.Group;
+       import spark.components.Scroller;
+       import spark.components.TextArea;
+       import spark.components.supportClasses.StyleableTextField;
+       import spark.events.CaretBoundsChangeEvent;
+       import spark.skins.android4.supportClasses.TextSkinBase;
+       
+       use namespace mx_internal;
+       
+       /**
+        *  ActionScript-based skin for TextArea components in mobile 
applications.
+        * 
+        * @see spark.components.TextArea
+        * 
+        *  @langversion 3.0
+        *  @playerversion Flash 10
+        *  @playerversion AIR 2.5 
+        *  @productversion Flex 4.5
+        */
+       public class TextAreaSkin extends TextSkinBase 
+       {
+               /**
+                *  @private
+                *  Right-margin of iOS native text control when editing on a 
retina display
+                *  based on fontSize 32.
+                */
+               mx_internal static var IOS_RIGHT_MARGIN_320:Number = 19;
+               
+               /**
+                *  @private
+                *  Right-margin of iOS native text control when editing on a 
retina display
+                *  based on fontSize 16 scaling from applicationDPI 160.
+                */
+               mx_internal static var 
IOS_RIGHT_MARGIN_160_SCALED_TO_320:Number = 9.4;
+               
+               /**
+                *  @private
+                *  Right-margin of iOS native text control when editing on a 
standard display
+                *  based on fontSize 16 and runtimeDPI 160.
+                */
+               mx_internal static var IOS_RIGHT_MARGIN_160:Number = 20.6;
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Constructor
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  Constructor.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 2.5
+                *  @productversion Flex 4.5
+                */
+               public function TextAreaSkin()
+               {
+                       super();
+                       
+                       addEventListener(Event.RESIZE, resizeHandler);
+                       
+                       switch (applicationDPI)
+                       {
+                               case DPIClassification.DPI_640:
+                               {
+                                       measuredDefaultWidth = 1024;
+                                       measuredDefaultHeight = 212;
+                                       layoutBorderSize = 4;
+                                       flatheight = 9;
+                                       break;
+                               }
+                               case DPIClassification.DPI_480:
+                               {
+                                       measuredDefaultWidth = 880;
+                                       measuredDefaultHeight = 140;
+                                       layoutBorderSize = 3;
+                                       flatheight = 7; 
+                                       break;
+                               }
+                               case DPIClassification.DPI_320:
+                               {
+                                       measuredDefaultWidth = 612;
+                                       measuredDefaultHeight = 106;
+                                       layoutBorderSize = 2;
+                                       flatheight = 6;         
+                                       break;
+                               }
+                               case DPIClassification.DPI_240:
+                               {
+                                       measuredDefaultWidth = 440;
+                                       measuredDefaultHeight = 70;
+                                       layoutBorderSize = 2;
+                                       flatheight = 5;
+                                       break;
+                               }
+                               case DPIClassification.DPI_120:
+                               {
+                                       measuredDefaultWidth = 220;
+                                       measuredDefaultHeight = 35;
+                                       layoutBorderSize = 1;
+                                       flatheight = 2;
+                                       break;
+                               }
+                               default:
+                               {
+                                       measuredDefaultWidth = 306;
+                                       measuredDefaultHeight = 53;
+                                       layoutBorderSize = 1;
+                                       flatheight = 3; 
+                                       break;
+                               }
+                       }
+                       addEventListener(FocusEvent.FOCUS_IN, 
focusChangeHandler);
+                       addEventListener(FocusEvent.FOCUS_OUT, 
focusChangeHandler);
+               }
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Skin parts
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  Scroller skin part.
+                *
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 2.5 
+                *  @productversion Flex 4.5
+                */ 
+               public var scroller:Scroller;
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Properties
+               //
+               
//--------------------------------------------------------------------------
+               
+               /** 
+                *  @copy spark.skins.spark.ApplicationSkin#hostComponent
+                */
+               public var hostComponent:TextArea;
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Variables
+               //
+               
//--------------------------------------------------------------------------
+               
+               protected var isFocused:Boolean = false;
+               
+               protected var flatheight:uint;
+               
+               /**
+                *  @private
+                *  The width of the component on the previous layout manager 
+                *  pass.  This gets set in updateDisplayList() and used in 
measure() on 
+                *  the next layout pass.  This is so our "guessed width" in 
measure() 
+                *  will be as accurate as possible since textDisplay is 
multiline and 
+                *  the textDisplay height is dependent on the width.
+                * 
+                *  In the constructor this is actually set based on the DPI.
+                */
+               mx_internal var oldUnscaledWidth:Number;
+               
+               private var textDisplayGroup:Group;
+               private var _isIOS:Boolean;
+               private var invalidateCaretPosition:Boolean = true;
+               private var oldCaretBounds:Rectangle = new Rectangle(-1, -1, 
-1, -1);
+               private var lastTextHeight:Number;
+               private var lastTextWidth:Number;
+               
+               private var isTextDisplayTall:Boolean = true;
+               private var growTextDisplay:Boolean = false;
+               private var shrinkTextDisplay:Boolean = false;
+               
+               
//--------------------------------------------------------------------------
+               //
+               //  Overridden methods
+               //
+               
//--------------------------------------------------------------------------
+               
+               /**
+                *  @private
+                */
+               override protected function createChildren():void
+               {
+                       if (!textDisplay)
+                       {
+                               // wrap StyleableTextField in UIComponent
+                               textDisplay = 
StyleableTextField(createInFontContext(StyleableTextField));
+                               textDisplay.styleName = this;
+                               textDisplay.multiline = true;
+                               textDisplay.editable = true;
+                               textDisplay.lineBreak = getStyle("lineBreak");
+                               textDisplay.useTightTextBounds = false;
+                               textDisplay.scrollToRangeDelegate = 
scrollToRange;
+                               
+                               // on iOS, resize the TextField and let the 
native control handle scrolling
+                               _isIOS = Platform.isIOS;
+                               
+                               if (_isIOS)
+                               {
+                                       // hard-coded rightMargin for iOS 
native text control
+                                       // this value is independent of the 
paddingRight style
+                                       var rightMargin:Number = 0;
+                                       var isRetina:Boolean = false;
+                                       var isScaling160to320:Boolean = false;
+                                       
+                                       // check for scaling
+                                       if ("runtimeDPI" in 
FlexGlobals.topLevelApplication)
+                                       {
+                                               var runtimeDPI:Number = 
FlexGlobals.topLevelApplication.runtimeDPI as Number;
+                                               isRetina = (runtimeDPI == 
DPIClassification.DPI_320);
+                                               isScaling160to320 = isRetina
+                                                       && (applicationDPI == 
DPIClassification.DPI_160);
+                                       }
+                                       
+                                       if (isRetina && !isScaling160to320)
+                                               rightMargin = 
IOS_RIGHT_MARGIN_320;
+                                       else if (isRetina && isScaling160to320)
+                                               rightMargin = 
IOS_RIGHT_MARGIN_160_SCALED_TO_320;
+                                       else
+                                               rightMargin = 
IOS_RIGHT_MARGIN_160;
+                                       
+                                       textDisplay.rightMargin = rightMargin;
+                               }
+                               else
+                               {
+                                       
textDisplay.addEventListener(KeyboardEvent.KEY_DOWN, textDisplay_keyHandler);
+                               }
+                               
+                               textDisplay.addEventListener(Event.CHANGE, 
textDisplay_changeHandler);
+                               
textDisplay.addEventListener(FlexEvent.VALUE_COMMIT, textDisplay_changeHandler);
+                               textDisplay.addEventListener(Event.SCROLL, 
textDisplay_scrollHandler);
+                               // Use a lower priority so that the 
StyleableTextField event handler is called first. 
+                               // That handler cancels the event and we need 
to check for that case
+                               
textDisplay.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING, 
textDisplay_softKeyboardActivatingHandler, false, 
EventPriority.DEFAULT_HANDLER);
+                               
textDisplay.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, 
textDisplay_softKeyboardActivateHandler);
+                               
textDisplay.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, 
textDisplay_softKeyboardDeactivateHandler);
+                               
+                               textDisplay.left = getStyle("paddingLeft");
+                               textDisplay.top = getStyle("paddingTop");
+                               textDisplay.right = getStyle("paddingRight");
+                               textDisplay.bottom = getStyle("paddingBottom");
+                               
+                               // wrap StyleableTextComponent in Group for 
viewport
+                               textDisplayGroup = new Group();
+                               textDisplayGroup.clipAndEnableScrolling = true;
+                               textDisplayGroup.addElement(textDisplay);
+                       }
+                       
+                       if (!scroller)
+                       {
+                               scroller = new Scroller();
+                               scroller.minViewportInset = 0;
+                               scroller.measuredSizeIncludesScrollBars = false;
+                               scroller.ensureElementIsVisibleForSoftKeyboard 
= false;
+                               
+                               addChild(scroller);
+                       }
+                       
+                       if (!scroller.viewport)
+                               scroller.viewport = textDisplayGroup;
+                       
+                       super.createChildren();
+               }
+               
+               /**
+                *  @private
+                *  TextArea prompt supports wrapping and multiline
+                */
+               override protected function 
createPromptDisplay():StyleableTextField
+               {
+                       var prompt:StyleableTextField = 
super.createPromptDisplay();
+                       prompt.editable = true;
+                       prompt.wordWrap = true;
+                       
+                       return prompt;
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function measure():void
+               {
+                       super.measure();
+                       
+                       var paddingTop:Number = getStyle("paddingTop");
+                       var paddingBottom:Number = getStyle("paddingBottom");
+                       var paddingLeft:Number = getStyle("paddingLeft");
+                       var paddingRight:Number = getStyle("paddingRight");
+                       
+                       // TextDisplay always defaults to 440 pixels wide (the 
value is DPI dependent), 
+                       // and tall enough to show all text.
+                       // 
+                       // You can set an explicit width and the height will 
adjust accordingly. The opposite
+                       // is not true: setting an explicit height will not 
adjust the width accordingly.
+                       
+                       measuredWidth = measuredDefaultWidth;
+                       
+                       // now we need to measure textDisplay's height.  
Unfortunately, this is tricky and 
+                       // is dependent on textDisplay's width.  Let's use the 
heuristic that our width 
+                       // is the same as our last width.
+                       // We don't use layoutMeasuredWidth, because that value 
is just a constant and doesn't
+                       // take into account the fact that the TextArea could 
have an explicitWidth or could 
+                       // be constrained by some value.  However, we still 
default oldTextDisplayWidth to 
+                       // be layoutMeasuredWidth the first time through.
+                       var textDisplayEstimatedWidth:Number = oldUnscaledWidth 
- paddingLeft - paddingRight;
+                       
+                       // now we need to measure textDisplay's height.  
Unfortunately, this is tricky and 
+                       // is dependent on textDisplay's width.  
+                       // Use the old textDisplay width as an estimte for the 
new one.  
+                       // If we are wrong, we'll find out in 
updateDisplayList()
+                       textDisplay.commitStyles();
+                       
+                       // Clear min sizes first.
+                       textDisplay.minWidth = textDisplay.minHeight = NaN;
+                       
+                       // If lineBreak == explicit, always use NaN for 
estimated width
+                       if (getStyle("lineBreak") == "explicit")
+                               textDisplayEstimatedWidth = NaN;
+                       
+                       setElementSize(textDisplay, textDisplayEstimatedWidth, 
NaN);
+                       
+                       measuredHeight = getElementPreferredHeight(textDisplay) 
+ paddingTop + paddingBottom;
+               }
+               
+               /**
+                *  @private
+                */
+               override protected function 
layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
+               {
+                       super.layoutContents(unscaledWidth, unscaledHeight);
+                       
+                       // position & size border
+                       if (border)
+                       {
+                               setElementSize(border, unscaledWidth, 
unscaledHeight);
+                               setElementPosition(border, 0, 0);
+                       }
+                       
+                       setElementSize(scroller, unscaledWidth, unscaledHeight);
+                       setElementPosition(scroller, 0, 0);
+                       
+                       // position & size the text
+                       var explicitLineBreak:Boolean = getStyle("lineBreak") 
== "explicit";
+                       var paddingLeft:Number = getStyle("paddingLeft");
+                       var paddingRight:Number = getStyle("paddingRight");
+                       var paddingTop:Number = getStyle("paddingTop");
+                       var paddingBottom:Number = getStyle("paddingBottom");
+                       
+                       var unscaledTextWidth:Number = unscaledWidth - 
paddingLeft - paddingRight;
+                       var unscaledTextHeight:Number = unscaledHeight - 
paddingTop - paddingBottom;
+                       var textHeight:Number;
+                       var textWidth:Number = explicitLineBreak ? 
textDisplay.measuredTextSize.x : unscaledTextWidth;
+                       
+                       var lineIndex:int;
+                       var topCharIndex:int;
+                       var charBounds:Rectangle;
+                       
+                       // grab old measured textDisplay height before resizing 
it
+                       var oldPreferredTextHeight:Number = 
getElementPreferredHeight(textDisplay);
+                       
+                       // set width first to measure height correctly
+                       textDisplay.commitStyles();
+                       textDisplay.setLayoutBoundsSize(textWidth, NaN);
+                       
+                       // In iOS, when we go into editing mode, the runtime 
overlays a native 
+                       // text control over the textDisplay. In order to 
prevent the text 
+                       // from overflowing the component and to get scrolling 
support, the 
+                       // native text control must be the same size as the 
TextArea
+                       if (_isIOS)
+                       {
+                               if (shrinkTextDisplay)
+                               {
+                                       // Switching to edit mode. Convert from 
viewport scrolling to 
+                                       // TextField scrolling
+                                       var vsp:Number = 
textDisplayGroup.verticalScrollPosition;
+                                       
+                                       var lineMetrics:TextLineMetrics = 
textDisplay.getLineMetrics(0);
+                                       var lineHeight:Number = 
lineMetrics.ascent + lineMetrics.descent;
+                                       
+                                       // TODO Figure out how to get the x 
offset. Right now is hard coded to 2
+                                       // At least half the line should be 
showing before we scroll to that line
+                                       // This makes the conversion from pixel 
to line based scrolling a little less jumpy
+                                       lineIndex = 
textDisplay.getLineIndexAtPoint(2, vsp + lineHeight / 2) + 1;
+                                       textDisplayGroup.verticalScrollPosition 
= 0;
+                                       isTextDisplayTall = false;
+                                       //trace("TAS.layoutContents shrinkText 
vsp",vsp,"lineIndex",lineIndex);
+                               }
+                                       
+                               else if (growTextDisplay)
+                               {
+                                       // Leaving edit mode. Convert from 
TextField scrolling to 
+                                       // viewport scrolling
+                                       var scrollV:Number = 
textDisplay.scrollV;
+                                       
+                                       // TODO (jszeto) investigate using 
lineMetrics.lineHeight * scrollV instead of getCharBoundaries
+                                       topCharIndex = 
textDisplay.getLineOffset(scrollV - 1);
+                                       charBounds = 
textDisplay.getCharBoundaries(topCharIndex);
+                                       // If the charBounds is null, just set 
vsp to 0
+                                       if (charBounds == null)
+                                               charBounds = new Rectangle(0, 
0, 0, 0);
+                                       textDisplay.scrollV = 1;
+                                       isTextDisplayTall = true;
+                                       //trace("TAS.layoutContents growText 
scrollV",scrollV,"topCharIndex",topCharIndex,"charBounds",charBounds);
+                               }
+                       }
+                       
+                       // TextField height should match its content or the 
TextArea bounds at minimum
+                       // iOS special case to prevent Flex Scroller scrolling 
when editable
+                       if (isTextDisplayTall)
+                               textHeight = 
Math.max(textDisplay.measuredTextSize.y, unscaledTextHeight);
+                       else
+                               textHeight = unscaledTextHeight;
+                       
+                       // FIXME (jasonsj): iOS native scroll bar appears even 
when explictHeight
+                       //                  is not specified. Focus-in is jumpy.
+                       
+                       if (promptDisplay)
+                       {
+                               promptDisplay.commitStyles();
+                               setElementSize(promptDisplay, 
unscaledTextWidth, textHeight);
+                               setElementPosition(promptDisplay, paddingLeft, 
paddingTop);
+                               
+                               // no need to update textDisplay if 
promptDisplay is present
+                               return;
+                       }
+                       
+                       // keep track of oldUnscaledWidth so we have a good 
guess as to the width 
+                       // of the textDisplay on the next measure() pass
+                       oldUnscaledWidth = unscaledWidth;
+                       
+                       // set the width of textDisplay to textWidth.
+                       // set the height to oldTextHeight.  If the height's 
actually wrong, 
+                       // we'll invalidateSize() and go through this layout 
pass again anyways
+                       setElementSize(textDisplay, textWidth, textHeight);
+                       
+                       // Set minWidth/Height on the text so the 
textDisplayGroup sizes accordingly
+                       textDisplay.minWidth = textWidth;
+                       textDisplay.minHeight = textHeight;
+                       textDisplayGroup.invalidateDisplayList();
+                       
+                       // grab new measured textDisplay height after the 
textDisplay has taken its final width
+                       var newPreferredTextHeight:Number = 
getElementPreferredHeight(textDisplay);
+                       
+                       // if the resize caused the textDisplay's height to 
change (because of 
+                       // text reflow), then we need to remeasure ourselves 
with our new width
+                       if (oldPreferredTextHeight != newPreferredTextHeight)
+                               invalidateSize();
+                       
+                       if (_isIOS)
+                       {
+                               if (shrinkTextDisplay)
+                               {
+                                       scroller.validateNow();
+                                       textDisplay.scrollV = lineIndex;
+                               }
+                               else if (growTextDisplay)
+                               {
+                                       scroller.validateNow();
+                                       textDisplayGroup.verticalScrollPosition 
= charBounds.y;
+                               }               
+                               
+                               shrinkTextDisplay = false;
+                               growTextDisplay = false;
+                       }
+                       
+                       //trace("TAS.layoutContents 
tH",textHeight,"tW",textWidth,"invalidateCaret",invalidateCaretPosition);
+                       
+                       // checking if text fits in TextArea
+                       // does not apply to iOS due to native text editing and 
scrolling
+                       // invalidateCaretPosition will never be true for iOS
+                       if (invalidateCaretPosition && isTextDisplayTall)
+                       {
+                               // if the caret is outside the viewport, update 
the Group verticalScrollPosition
+                               var charIndex:int = 
textDisplay.selectionBeginIndex;
+                               var caretBounds:Rectangle = 
textDisplay.getCharBoundaries(charIndex);
+                               lineIndex = 
textDisplay.getLineIndexOfChar(charIndex);
+                               
+                               // getCharBoundaries() returns null for new 
lines
+                               if (!caretBounds)
+                               {
+                                       // temporarily insert a character at 
the caretIndex
+                                       textDisplay.replaceText(charIndex, 
charIndex, "W");
+                                       caretBounds = 
textDisplay.getCharBoundaries(charIndex);
+                                       lineIndex = 
textDisplay.getLineIndexOfChar(charIndex);
+                                       textDisplay.replaceText(charIndex, 
charIndex + 1, "");   
+                               }
+                               
+                               if (caretBounds)
+                               {
+                                       // Scroll the internal Scroller to 
ensure the caret is visible
+                                       if (textHeight > unscaledTextHeight)
+                                       {
+                                               
+                                               if (charIndex == 
textDisplay.text.length)
+                                               {
+                                                       // Make sure 
textDisplayGroup is validated, otherwise the 
+                                                       // 
verticalScrollPosition may be out of bounds, which will
+                                                       // cause a bounce 
effect.
+                                                       
textDisplayGroup.validateNow();
+                                                       
textDisplayGroup.verticalScrollPosition = textHeight;
+                                               }
+                                               else
+                                               {
+                                                       // caretTopPositon and 
caretBottomPosition are TextField-relative positions
+                                                       // the TextField is 
inset by padding styles of the TextArea (via the VGroup)
+                                                       
+                                                       // adjust top position 
to 0 when on the first line
+                                                       // caretTopPosition 
will be negative when off stage
+                                                       var 
caretTopPosition:Number = ((caretBounds.y) < 0 || (lineIndex == 0))
+                                                               ? 0 : 
caretBounds.y;
+                                                       
+                                                       // caretBottomPosition 
is the y coordinate of the bottom bounds of the caret
+                                                       var 
caretBottomPosition:Number = caretBounds.y + caretBounds.height;
+                                                       
+                                                       // note that 
verticalScrollPosition min/max do not account for padding
+                                                       var vspTop:Number = 
textDisplayGroup.verticalScrollPosition;
+                                                       
+                                                       // vspBottom should be 
the max visible Y in the TextField
+                                                       // coordinate space.
+                                                       // remove paddingBottom 
for some clearance between caret and border
+                                                       var vspBottom:Number = 
vspTop + unscaledHeight - paddingTop - paddingBottom;
+                                                       
+                                                       // is the caret in or 
below the padding and viewport?
+                                                       if (caretBottomPosition 
> vspBottom)
+                                                       {
+                                                               // adjust 
caretBottomPosition to max scroll position when on the last line
+                                                               if (lineIndex + 
1 == textDisplay.numLines)
+                                                               {
+                                                                       // use 
textHeight+paddings instead of textDisplayGroup.contentHeight
+                                                                       // 
Group has not been resized by this point
+                                                                       
textDisplayGroup.verticalScrollPosition = (textHeight + paddingTop + 
paddingBottom) - textDisplayGroup.height;
+                                                               }
+                                                               else
+                                                               {
+                                                                       // 
bottom edge of the caret moves just inside the bottom edge of the scroller
+                                                                       // add 
delta between caret and vspBottom
+                                                                       
textDisplayGroup.verticalScrollPosition = vspTop + (caretBottomPosition - 
vspBottom);
+                                                               }
+                                                       }
+                                                               // is the caret 
above the viewport?
+                                                       else if 
(caretTopPosition < vspTop)
+                                                       {
+                                                               // top edge of 
the caret moves inside the top edge of the scroller
+                                                               
textDisplayGroup.verticalScrollPosition = caretTopPosition;
+                                                       }
+                                               }
+                                               
+                                               scroller.validateNow();
+                                       }
+                                       
+                                       // Convert to local coordinates
+                                       // Dispatch an event for an ancestor 
Scroller
+                                       // It will scroll the TextArea so the 
caret is in view
+                                       convertBoundsToLocal(caretBounds);
+                                       if (oldCaretBounds == null || 
caretBounds.bottom != oldCaretBounds.bottom || caretBounds.top != 
oldCaretBounds.top)
+                                       {
+                                               //trace("TAS.layoutContents 
send caret CHANGE");
+                                               dispatchEvent(new 
CaretBoundsChangeEvent(CaretBoundsChangeEvent.CARET_BOUNDS_CHANGE,true,true,oldCaretBounds,caretBounds));
+                                       }
+                                       
+                                       oldCaretBounds = caretBounds;   
+                               }
+                               
+                               invalidateCaretPosition = false;
+                       }
+                       
+                       // Make sure final scroll position is valid
+                       if (isTextDisplayTall)
+                               snapTextScrollPosition();
+               }
+               
+               override protected function 
drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
+               {
+                       super.drawBackground(unscaledWidth, unscaledHeight);
+                       
+                       var contentBackgroundColor:uint = 
getStyle("contentBackgroundColor");
+                       var contentBackgroundAlpha:Number = 
getStyle("contentBackgroundAlpha"); 
+                       //change border color and thickness when in focus
+                       var borderColor:uint = isFocused ? 
getStyle("focusColor") : getStyle("borderColor");
+                       var selectWidth:uint = isFocused ? layoutBorderSize + 1 
: layoutBorderSize;
+                       if (isNaN(contentBackgroundAlpha))
+                       {
+                               contentBackgroundAlpha = 1;
+                       }        
+                       if (getStyle("contentBackgroundBorder") == "flat")
+                       {               
+                               var halfGap:int = flatheight * 2;
+                               //background
+                               graphics.beginFill(contentBackgroundColor, 
contentBackgroundAlpha);
+                               graphics.drawRect(0, 0, unscaledWidth, 
unscaledHeight - flatheight);
+                               graphics.endFill();
+                               //begin flat border
+                               graphics.beginFill(borderColor, 1);
+                               //left half border
+                               graphics.drawRect(0, unscaledHeight - halfGap, 
selectWidth, flatheight );
+                               //bottom border
+                               graphics.drawRect(0, unscaledHeight - 
flatheight, unscaledWidth, selectWidth);
+                               //right border
+                               graphics.drawRect(unscaledWidth - selectWidth, 
unscaledHeight - halfGap, selectWidth, flatheight);
+                               graphics.endFill();
+                       }
+                       else if (getStyle("contentBackgroundBorder") == 
"rectangle")
+                       {
+                               var borderWidth:uint = layoutBorderSize * 2;
+                               //rectangle border and background
+                               graphics.lineStyle(selectWidth, borderColor, 1);
+                               graphics.beginFill(contentBackgroundColor, 
contentBackgroundAlpha);
+                               graphics.drawRect(layoutBorderSize, 
layoutBorderSize, unscaledWidth - borderWidth, unscaledHeight - borderWidth);
+                               graphics.endFill();
+                       }
+               }
+               
+               /**
+                *  @private
+                *  Make sure the scroll positions are valid, and adjust if 
needed.
+                */
+               private function snapTextScrollPosition():void
+               {
+                       var maxHsp:Number = textDisplayGroup.contentWidth > 
textDisplayGroup.width ? 
+                               
textDisplayGroup.contentWidth-textDisplayGroup.width : 0; 
+                       textDisplayGroup.horizontalScrollPosition = 
+                               
Math.min(Math.max(0,textDisplayGroup.horizontalScrollPosition),maxHsp);
+                       
+                       var maxVsp:Number = textDisplayGroup.contentHeight > 
textDisplayGroup.height ? 
+                               
textDisplayGroup.contentHeight-textDisplayGroup.height : 0; 
+                       
+                       textDisplayGroup.verticalScrollPosition = 
+                               
Math.min(Math.max(0,textDisplayGroup.verticalScrollPosition),maxVsp);
+               }
+               
+               /**
+                *  @private
+                *  Get the bounds of the caret
+                */    
+               private function getCaretBounds():Rectangle
+               {
+                       var charIndex:int = textDisplay.selectionBeginIndex;
+                       var caretBounds:Rectangle = 
textDisplay.getCharBoundaries(charIndex);
+                       
+                       if (!caretBounds)
+                       {
+                               textDisplay.replaceText(charIndex, charIndex, 
"W");
+                               caretBounds = 
textDisplay.getCharBoundaries(charIndex);
+                               textDisplay.replaceText(charIndex, charIndex + 
1, "");
+                       }
+                       
+                       return caretBounds;
+               }
+               
+               /**
+                *  @private
+                *  Convert bounds from textDisplay to local coordinates
+                */
+               private function convertBoundsToLocal(bounds:Rectangle):void
+               {
+                       if (bounds)
+                       {
+                               var position:Point = new Point(bounds.x, 
bounds.y);
+                               position = textDisplay.localToGlobal(position);
+                               position = globalToLocal(position);
+                               bounds.x = position.x;
+                               bounds.y = position.y;
+                       }
+               }
+               
+               /**
+                *  @private
+                */
+               private function scrollToRange(anchorPosition:int, 
activePosition:int):void
+               {
+                       var pos:int = Math.min(anchorPosition, activePosition);
+                       var bounds:Rectangle = 
textDisplay.getCharBoundaries(pos);
+                       var vsp:int = textDisplayGroup.verticalScrollPosition;
+                       var paddingTop:Number = getStyle("paddingTop");
+                       var paddingBottom:Number = getStyle("paddingBottom");
+                       
+                       if (bounds && (bounds.top < vsp - paddingTop || 
+                               bounds.bottom > vsp + unscaledHeight - 
paddingTop - paddingBottom))
+                       {
+                               textDisplayGroup.verticalScrollPosition = 
bounds.top + paddingTop;
+                               snapTextScrollPosition();
+                       }
+               }
+               
+               /**
+                *  @private
+                *  Handle size and caret position changes that occur when text 
content
+                *  changes.
+                */
+               private function textDisplay_changeHandler(event:Event):void
+               {
+                       var tH:Number = textDisplay.textHeight;
+                       var tW:Number = textDisplay.textWidth;
+                       var explicitLineBreak:Boolean = getStyle("lineBreak") 
== "explicit";
+                       
+                       // Size and caret position have changed if the text 
height is different or
+                       // the text width is different and we aren't word 
wrapping
+                       if (tH != lastTextHeight || ( explicitLineBreak && tW 
!= lastTextWidth))
+                       {
+                               invalidateSize();
+                               invalidateDisplayList();
+                               invalidateCaretPosition = true;   
+                       }
+                       
+                       lastTextHeight = tH;
+                       lastTextWidth = tW;
+               }
+               
+               /**
+                *  @private
+                *  Cancels any native scroll that the Flash Player attempts to 
do
+                */
+               private function textDisplay_scrollHandler(event:Event):void
+               {
+                       // if iOS, let the OS handle scrolling
+                       if (_isIOS)
+                               return;
+                       
+                       // If not IOS, we will handle scrolling, so don't let 
the native
+                       // flash textfield scroll at all.
+                       if (textDisplay.scrollV > 1)
+                               textDisplay.scrollV = 1;
+                       if (textDisplay.scrollH > 0)
+                               textDisplay.scrollH = 0;
+               }
+               
+               /**
+                *  @private
+                *  Adjust viewport when using key navigation
+                */
+               private function 
textDisplay_keyHandler(event:KeyboardEvent):void
+               {
+                       // update scroll position when caret changes
+                       if ((event.keyCode == Keyboard.UP
+                               || event.keyCode == Keyboard.DOWN
+                               || event.keyCode == Keyboard.LEFT
+                               || event.keyCode == Keyboard.RIGHT))
+                       {
+                               invalidateDisplayList();
+                               invalidateCaretPosition = true;
+                       }
+                       
+                       // Change event is not always sent when delete key is 
pressed, so
+                       // invalidate the size here
+                       if (event.keyCode == Keyboard.BACKSPACE)
+                       {
+                               invalidateSize();
+                       }
+               }
+               
+               /**
+                *  @private
+                *  When entering edit mode on iOS, we need to shrink the 
textDisplay to 
+                *  the size of the TextArea  
+                */ 
+               private function 
textDisplay_softKeyboardActivatingHandler(event:SoftKeyboardEvent):void
+               {
+                       if (event.isDefaultPrevented())
+                               return;
+                       
+                       if (_isIOS && isTextDisplayTall)
+                       {
+                               //trace("TAS.SK ACTIVATING targ",event.target);
+                               shrinkTextDisplay = true;
+                               invalidateDisplayList();
+                               validateNow();
+                       }
+               }  
+               
+               /**
+                *  @private
+                *  Send a caret change event to an ancestor Scroller
+                */
+               private function 
textDisplay_softKeyboardActivateHandler(event:SoftKeyboardEvent):void
+               {
+                       var keyboardRect:Rectangle = stage.softKeyboardRect;
+                       
+                       if (keyboardRect.width > 0 && keyboardRect.height > 0)
+                       {
+                               var newCaretBounds:Rectangle = getCaretBounds();
+                               convertBoundsToLocal(newCaretBounds);
+                               
+                               if (oldCaretBounds != newCaretBounds)
+                               {
+                                       //trace("TAS.SK 
ACTIVATE",keyboardRect,"dispatch caret CHANGE","newCaretBounds",newCaretBounds);
+                                       dispatchEvent(new 
CaretBoundsChangeEvent(CaretBoundsChangeEvent.CARET_BOUNDS_CHANGE,true,true,oldCaretBounds,newCaretBounds));
+                                       oldCaretBounds = newCaretBounds;
+                               }
+                       }
+               }
+               
+               /**
+                *  @private
+                *  On iOS, when leaving edit mode, we need to restore the 
textDisplay to the
+                *  height of the text.
+                */  
+               private function 
textDisplay_softKeyboardDeactivateHandler(event:SoftKeyboardEvent):void
+               {
+                       if (_isIOS && !isTextDisplayTall)
+                       {
+                               growTextDisplay = true;
+                               invalidateDisplayList();
+                       }
+               }
+               
+               /**
+                *  @private
+                */
+               private function resizeHandler(event:Event):void
+               {
+                       // Resizing needs to tickle the TextArea's internal 
auto-scroll logic
+                       invalidateCaretPosition = true;
+                       invalidateDisplayList();
+               }
+               
+               /**
+                *  @private
+                */
+               override public function styleChanged(styleProp:String):void
+               {
+                       super.styleChanged(styleProp);
+                       
+                       // propogate styleChanged explicitly to textDisplay
+                       if (textDisplay)
+                               textDisplay.styleChanged(styleProp);
+                       
+                       // Check for padding style changes
+                       if (!styleProp || styleProp == "styleName" || 
styleProp.indexOf("padding") >= 0)
+                       {
+                               if (textDisplay)
+                               {
+                                       textDisplay.left = 
getStyle("paddingLeft");
+                                       textDisplay.top = 
getStyle("paddingTop");
+                                       textDisplay.right = 
getStyle("paddingRight");
+                                       textDisplay.bottom = 
getStyle("paddingBottom");
+                               }
+                       }
+               }
+               
+               private function focusChangeHandler(event:FocusEvent):void
+               {
+                       isFocused = event.type == FocusEvent.FOCUS_IN;
+                       invalidateDisplayList();                
+               }
+               
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarSkin.as
----------------------------------------------------------------------
diff --git 
a/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarSkin.as
new file mode 100644
index 0000000..f65b679
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarSkin.as
@@ -0,0 +1,105 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package spark.skins.android4
+{
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+/**
+ *  ActionScript-based skin for TextAreaVScrollBar components in mobile 
applications.
+ * 
+ *  @langversion 3.0
+ *  @playerversion Flash 10.1
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ */
+public class TextAreaVScrollBarSkin extends VScrollBarSkin
+{
+    /**
+     *  Constructor. 
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     * 
+     */ 
+    public function TextAreaVScrollBarSkin()
+    {
+        super();
+
+        thumbSkinClass = TextAreaVScrollBarThumbSkin;
+        var paddingRight:int;
+        var paddingVertical:int;
+
+        switch (applicationDPI)
+        {
+                       case DPIClassification.DPI_640:
+                       {
+                               minWidth = 30;
+                               paddingRight = 
TextAreaVScrollBarThumbSkin.PADDING_RIGHT_640DPI;
+                               paddingVertical = 
TextAreaVScrollBarThumbSkin.PADDING_VERTICAL_640DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_480:
+                       {
+                               minWidth = 22;
+                               paddingRight = 
TextAreaVScrollBarThumbSkin.PADDING_RIGHT_480DPI;
+                               paddingVertical = 
TextAreaVScrollBarThumbSkin.PADDING_VERTICAL_480DPI;
+                               break;
+                       }
+            case DPIClassification.DPI_320:
+            {
+                minWidth = 15;
+                paddingRight = 
TextAreaVScrollBarThumbSkin.PADDING_RIGHT_320DPI;
+                paddingVertical = 
TextAreaVScrollBarThumbSkin.PADDING_VERTICAL_320DPI;
+                break;
+            }
+                       case DPIClassification.DPI_240:
+                       {
+                               minWidth = 11;
+                               paddingRight = 
TextAreaVScrollBarThumbSkin.PADDING_RIGHT_240DPI;
+                               paddingVertical = 
TextAreaVScrollBarThumbSkin.PADDING_VERTICAL_240DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_120:
+                       {
+                               minWidth = 6;
+                               paddingRight = 
TextAreaVScrollBarThumbSkin.PADDING_RIGHT_120DPI;
+                               paddingVertical = 
TextAreaVScrollBarThumbSkin.PADDING_VERTICAL_120DPI;
+                               break;
+                       }
+            default:
+            {
+                // default DPI_160
+                minWidth = 9;
+                paddingRight = 
TextAreaVScrollBarThumbSkin.PADDING_RIGHT_DEFAULTDPI;
+                paddingVertical = 
TextAreaVScrollBarThumbSkin.PADDING_VERTICAL_DEFAULTDPI;
+                break;
+            }
+        }
+        
+        // The minimum height is set such that, at it's smallest size, the 
thumb appears
+        // as high as it is wide.
+        minThumbHeight = (minWidth - paddingRight) + (paddingVertical * 2);  
+    }
+}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-examples/blob/539852e9/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarThumbSkin.as
----------------------------------------------------------------------
diff --git 
a/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarThumbSkin.as 
b/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarThumbSkin.as
new file mode 100644
index 0000000..5cc1ea0
--- /dev/null
+++ b/tourdeflexmobile/src/spark/skins/android4/TextAreaVScrollBarThumbSkin.as
@@ -0,0 +1,117 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package spark.skins.android4
+{
+import mx.core.DPIClassification;
+import mx.core.mx_internal;
+
+use namespace mx_internal;
+
+/**
+ *  The ActionScript-based skin used for TextAreaHScrollBarThumb components
+ *  in mobile applications.
+ * 
+ *  @langversion 3.0
+ *  @playerversion AIR 2.5 
+ *  @productversion Flex 4.5
+ * 
+ */
+public class TextAreaVScrollBarThumbSkin extends VScrollBarThumbSkin
+{
+    
//--------------------------------------------------------------------------
+    //
+    //  Class constants
+    //
+    
//--------------------------------------------------------------------------
+    
+    // These constants are also accessed from TextAreaVScrollBarSkin
+       mx_internal static const PADDING_RIGHT_640DPI:int = 16;
+       mx_internal static const PADDING_VERTICAL_640DPI:int = 24;
+       mx_internal static const PADDING_RIGHT_480DPI:int = 12;
+       mx_internal static const PADDING_VERTICAL_480DPI:int = 18;
+       mx_internal static const PADDING_RIGHT_320DPI:int = 8;
+    mx_internal static const PADDING_VERTICAL_320DPI:int = 12;
+       mx_internal static const PADDING_RIGHT_240DPI:int = 4;
+       mx_internal static const PADDING_VERTICAL_240DPI:int = 6;
+       mx_internal static const PADDING_RIGHT_120DPI:int = 2;
+       mx_internal static const PADDING_VERTICAL_120DPI:int = 3;
+    mx_internal static const PADDING_RIGHT_DEFAULTDPI:int = 4;
+    mx_internal static const PADDING_VERTICAL_DEFAULTDPI:int = 6;
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    
//-------------------------------------------------------------------------- 
+    /**
+     *  Constructor.
+     * 
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.5 
+     *  @productversion Flex 4.5
+     * 
+     */
+    public function TextAreaVScrollBarThumbSkin()
+    {
+        super();
+        
+        // Depending on density set padding
+        switch (applicationDPI)
+        {
+                       case DPIClassification.DPI_640:
+                       {
+                               paddingRight = PADDING_RIGHT_640DPI;
+                               paddingVertical = PADDING_VERTICAL_640DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_480:
+                       {
+                               paddingRight = PADDING_RIGHT_480DPI;
+                               paddingVertical = PADDING_VERTICAL_480DPI;
+                               break;
+                       }               
+            case DPIClassification.DPI_320:
+            {
+                paddingRight = PADDING_RIGHT_320DPI;
+                paddingVertical = PADDING_VERTICAL_320DPI;
+                break;
+            }
+                       case DPIClassification.DPI_240:
+                       {
+                               paddingRight = PADDING_RIGHT_240DPI;
+                               paddingVertical = PADDING_VERTICAL_240DPI;
+                               break;
+                       }
+                       case DPIClassification.DPI_120:
+                       {
+                               paddingRight = PADDING_RIGHT_120DPI;
+                               paddingVertical = PADDING_VERTICAL_120DPI;
+                               break;
+                       }
+            default:
+            {
+                paddingRight = PADDING_RIGHT_DEFAULTDPI;
+                paddingVertical = PADDING_VERTICAL_DEFAULTDPI;
+                break;
+            }
+        }
+    }
+}
+}
\ No newline at end of file

Reply via email to