Dodawanie obsługi klawiatury wirtualnej do obiektów interaktywnych

Flash Player 10.2 i nowsze wersje, AIR 2.6 i nowsze wersje (brak obsługi w systemie iOS)

Zazwyczaj klawiatura wirtualna jest otwierana tylko po dotknięciu obiektu TextField. Można skonfigurować wystąpienie klasy InteractiveObject w taki sposób, aby otwierało ono klawiaturę wirtualną w momencie aktywowania (przejęcia punktu skupienia).

W celu skonfigurowania wystąpienia klasy InteractiveObject tak, aby otwierało klawiaturę programową, należy ustawić dla jego właściwości needsSoftKeyboard wartość true . Klawiatura programowa jest automatycznie otwierana za każdym razem, gdy do właściwości focus stołu montażowego jest przypisywany obiekt. Ponadto, klawiaturę można unosić, wywołując metodę requestSoftKeyboard() klasy InteractiveObject.

Poniższy przykład przedstawia, jak zaprogramować obiekt InteractiveObject w taki sposób, aby działał jako pole wprowadzania tekstu. Klasa TextInput pokazana w przykładzie ustawia właściwość needsSoftKeyboard w taki sposób, aby w razie potrzeby była unoszona klawiatura. Następnie obiekt wykrywa zdarzenia keyDown i wprowadza wpisywany znak do pola.

W przykładzie zastosowano mechanizm obsługi tekstu programu Flash do dołączania i wyświetlania całego wpisywanego tekstu oraz obsługi niektórych ważnych zdarzeń. Dla uproszczenia w przykładzie nie zostało wdrożone w pełni funkcjonalne pole tekstowe.

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

Poniższa główna klasa aplikacji ilustruje, w jaki sposób używać klasy TextInput i zarządzać układem aplikacji, gdy jest unoszona klawiatura lub gdy zmienia się orientacja urządzenia. Klasa główna tworzy obiekt TextInput i ustawia jego obwiednię w taki sposób, aby stół montażowy został wypełniony. Klasa dostosowuje rozmiar obiektu TextInput, gdy jest unoszona klawiatura programowa lub gdy zmienia się rozmiar stołu montażowego. Klasa wykrywa zdarzenia klawiatury programowej pochodzące z obiektu TextInput i zdarzenia zmiany rozmiaru pochodzące ze stołu montażowego. Niezależnie od przyczyny zdarzenia aplikacja określa widoczny obszar stołu montażowego i zmienia rozmiar elementu sterującego wprowadzaniem danych w celu jego wypełnienia. Naturalnie w rzeczywistej aplikacji byłby wymagany bardziej wyrafinowany algorytm układu.

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; 
        } 
    } 
}
Uwaga: Gdy dla właściwości scaleMode jest ustawiona wartość noScale , stół montażowy wywołuje zdarzenia zmiany rozmiaru wyłącznie w odpowiedzi na zmianę orientacji. W innych trybach wymiary stołu montażowego nie zmieniają się. Zamiast tego dla równowagi jest skalowana zawartość.