Normally, the virtual keyboard only opens when a TextField object
is tapped. You can configure an instance of the InteractiveObject
class to open the virtual keyboard when it receives focus.
To configure an InteractiveObject instance to open the soft keyboard,
set its
needsSoftKeyboard
property to
true
.
Whenever the object is assigned to the stage focus property, the
soft keyboard automatically opens. In addition, you can raise the
keyboard by calling the
requestSoftKeyboard()
method
of the InteractiveObject.
The following example illustrates how you can program an InteractiveObject
to act as a text entry field. The TextInput class shown in the example
sets the
needsSoftKeyboard
property so that the
keyboard is raised when needed. The object then listens for
keyDown
events
and inserts the typed character into the field.
The example uses the Flash text engine to append and display
any typed text and handles some important events. For simplicity,
the example does not implement a full-featured text field.
package {
import flash.geom.Rectangle;
import flash.display.Sprite;
import flash.text.engine.TextElement;
import flash.text.engine.TextBlock;
import flash.events.MouseEvent;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.text.engine.TextLine;
import flash.text.engine.ElementFormat;
import flash.events.Event;
public class TextInput extends Sprite
{
public var text:String = " ";
public var textSize:Number = 24;
public var textColor:uint = 0x000000;
private var _bounds:Rectangle = new Rectangle( 0, 0, 100, textSize );
private var textElement: TextElement;
private var textBlock:TextBlock = new TextBlock();
public function TextInput( text:String = "" )
{
this.text = text;
this.scrollRect = _bounds;
this.focusRect= false;
//Enable keyboard support
this.needsSoftKeyboard = true;
this.addEventListener(MouseEvent.MOUSE_DOWN, onSelect);
this.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
this.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
//Setup text engine
textElement = new TextElement( text, new ElementFormat( null, textSize, textColor ) );
textBlock.content = textElement;
var firstLine:TextLine = textBlock.createTextLine( null, _bounds.width - 8 );
firstLine.x = 4;
firstLine.y = 4 + firstLine.totalHeight;
this.addChild( firstLine );
}
private function onSelect( event:MouseEvent ):void
{
stage.focus = this;
}
private function onFocusIn( event:FocusEvent ):void
{
this.addEventListener( KeyboardEvent.KEY_DOWN, onKey );
}
private function onFocusOut( event:FocusEvent ):void
{
this.removeEventListener( KeyboardEvent.KEY_UP, onKey );
}
private function onKey( event:KeyboardEvent ):void
{
textElement.replaceText( textElement.text.length, textElement.text.length, String.fromCharCode( event.charCode ) );
updateText();
}
public function set bounds( newBounds:Rectangle ):void
{
_bounds = newBounds.clone();
drawBackground();
updateText();
this.scrollRect = _bounds;
//force update to focus rect, if needed
if( this.stage!= null && this.focusRect && this.stage.focus == this )
this.stage.focus = this;
}
private function updateText():void
{
//clear text lines
while( this.numChildren > 0 ) this.removeChildAt( 0 );
//and recreate them
var textLine:TextLine = textBlock.createTextLine( null, _bounds.width - 8);
while ( textLine)
{
textLine.x = 4;
if( textLine.previousLine != null )
{
textLine.y = textLine.previousLine.y +
textLine.previousLine.totalHeight + 2;
}
else
{
textLine.y = 4 + textLine.totalHeight;
}
this.addChild(textLine);
textLine = textBlock.createTextLine(textLine, _bounds.width - 8 );
}
}
private function drawBackground():void
{
//draw background and border for the field
this.graphics.clear();
this.graphics.beginFill( 0xededed );
this.graphics.lineStyle( 1, 0x000000 );
this.graphics.drawRect( _bounds.x + 2, _bounds.y + 2, _bounds.width - 4, _bounds.height - 4);
this.graphics.endFill();
}
}
}
The following main application class illustrates how to use the
TextInput class and manage the application layout when the keyboard
is raised or the device orientation changes. The main class creates
a TextInput object and sets its bounds to fill the stage. The class
adjusts the size of the TextInput object when either the soft keyboard
is raised or the stage changes size. The class listens for soft
keyboard events from the TextInput object and resize events from
the stage. Irrespective of the cause of the event, the application
determines the visible area of the stage and resizes the input control
to fill it. Naturally, in a real application, you would need a more
sophisticated layout algorithm.
package {
import flash.display.MovieClip;
import flash.events.SoftKeyboardEvent;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
public class CustomTextField extends MovieClip {
private var customField:TextInput = new TextInput("Input text: ");
public function CustomTextField() {
this.stage.scaleMode = StageScaleMode.NO_SCALE;
this.stage.align = StageAlign.TOP_LEFT;
this.addChild( customField );
customField.bounds = new Rectangle( 0, 0, this.stage.stageWidth, this.stage.stageHeight );
//track soft keyboard and stage resize events
customField.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, onDisplayAreaChange );
customField.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, onDisplayAreaChange );
this.stage.addEventListener( Event.RESIZE, onDisplayAreaChange );
}
private function onDisplayAreaChange( event:Event ):void
{
//Fill the stage if possible, but avoid the area covered by a keyboard
var desiredBounds = new Rectangle( 0, 0, this.stage.stageWidth, this.stage.stageHeight );
if( this.stage.stageHeight - this.stage.softKeyboardRect.height < desiredBounds.height )
desiredBounds.height = this.stage.stageHeight - this.stage.softKeyboardRect.height;
customField.bounds = desiredBounds;
}
}
}
Note:
The stage only dispatches resize events in response to an
orientation change when the
scaleMode
property
is set to
noScale
. In other modes, the dimensions of
the stage do not change; instead, the content is scaled to compensate.