대화형 객체를 위한 가상 키보드 지원 추가

Flash Player 10.2 이상, AIR 2.6 이상(iOS에서는 지원되지 않음)

일반적으로 가상 키보드는 TextField 객체가 눌러질 때만 열립니다. 포커스를 받으면 가상 키보드를 열도록 InteractiveObject 클래스의 인스턴스를 구성할 수 있습니다.

소프트 키보드를 열도록 InteractiveObject 인스턴스를 구성하려면 해당 needsSoftKeyboard 속성을 true 로 설정합니다. 객체가 스테이지 포커스 속성에 할당되면 항상 소프트 키보드가 자동으로 열립니다. 또한 InteractiveObject의 requestSoftKeyboard() 메서드를 호출하여 키보드를 표시할 수도 있습니다.

다음 예제에서는 InteractiveObject가 텍스트 입력 필드로 사용되도록 프로그래밍하는 방법을 보여 줍니다. 예제에 나와 있는 TextInput 클래스는 필요한 경우 키보드가 표시되도록 needsSoftKeyboard 속성을 설정합니다. 그런 다음 이 객체는 keyDown 이벤트를 수신하고 입력된 문자를 필드에 삽입합니다.

이 예제에서는 Flash 텍스트 엔진을 사용하여 입력된 텍스트를 추가 및 표시하고 일부 중요한 이벤트를 처리합니다. 내용을 단순화하기 위해 완전한 기능을 갖춘 텍스트 필드는 구현하지 않습니다.

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 로 설정되어 있으면 스테이지가 방향 변경에 대해서만 resize 이벤트를 전달합니다. 다른 모드에서는 스테이지의 크기가 변경되지 않는 대신 보정을 위해 내용의 크기가 조절됩니다.