インタラクティブオブジェクトへの仮想キーボードサポートの追加

Flash Player 10.2 以降、AIR 2.6 以降(ただし、iOS ではサポートされていません)

通常、仮想キーボードは TextField オブジェクトがタップされたときのみ開きます。InteractiveObject クラスのインスタンスを設定し、そのインスタンスがフォーカスを受け取ったときに仮想キーボードを開くことができます。

ソフトキーボードを開くように InteractiveObject インスタンスを設定するには、そのインスタンスの needsSoftKeyboard プロパティを true に設定します。ステージの focus プロパティにオブジェクトが割り当てられるたびに、ソフトキーボードが自動的に開きます。また、InteractiveObject の requestSoftKeyboard() メソッドを呼び出してキーボードを表示できます。

次の例では、テキスト入力フィールドとして機能するように InteractiveObject をプログラミングする方法を示します。この例に示す TextInput クラスは、 needsSoftKeyboard プロパティを設定して、必要に応じてキーボードが表示されるようにします。次に、このオブジェクトは keyDown イベントをリッスンし、型指定された文字をフィールドに挿入します。

この例では、Flash Text Engine を使用して、型指定されたテキストを追加および表示し、いくつかの重要なイベントを処理します。わかりやすくするために、この例では、すべての機能を備えたテキストフィールドを実装していません。

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(); 
        } 
    } 
}

次のメインアプリケーションクラスでは、キーボードが表示されるときまたはデバイスの方向が変更されるときに、TextInput クラスを使用してアプリケーションレイアウトを管理する方法を示します。メインクラスは、TextInput オブジェクトを作成し、ステージに表示する境界を設定します。このクラスでは、ソフトキーボードが表示されるとき、またはステージのサイズが変更されるときに、TextInput オブジェクトのサイズを調整します。このクラスは、TextInput オブジェクトからのソフトキーボードイベントおよびステージからのサイズ変更イベントをリッスンします。イベントの原因に関係なく、アプリケーションではステージの表示可能な領域を特定し、ステージに表示する入力コントロールのサイズを変更します。ただし、実際のアプリケーションでは、より高度なレイアウトアルゴリズムが必要になります。

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; 
        } 
    } 
}
注意: scaleMode プロパティが noScale に設定されている場合、方向の変更に応答してステージが送出するのは、サイズ変更イベントのみです。他のモードでは、ステージのサイズが変更されません。その代わりに、コンテンツを拡大/縮小して補正します。