Добавление поддержки виртуальной клавиатуры для интерактивных объектов

Flash Player 10.2 и более поздних версий, AIR 2.6 и более поздних версий (но не поддерживается для iOS)

Обычно виртуальная клавиатура открывается только при касании объекта TextField. Можно настроить экземпляр класса InteractiveObject так, чтобы при получении им фокуса открывалась виртуальная клавиатура.

Чтобы настроить экземпляр InteractiveObject для вызова экранной клавиатуры, задайте его свойству needsSoftKeyboard значение true . Каждый раз при назначении объекта свойству focus рабочей области автоматически открывается виртуальная клавиатура. Кроме того, открыть клавиатуру можно вызовом метода requestSoftKeyboard() объекта InteractiveObject.

В следующем примере демонстрируется, как запрограммировать 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 . В других режимах размеры рабочей области не изменяются, а содержимое масштабируется с целью компенсации.