3

解決方法がわからないモバイルコンポーネントでTextAreaとTextInputを操作するときに、2つの問題が発生しました。1つは、TextAreaテキストが正しく配置されていないこと、もう1つは、他のコンポーネントと重なっていることです。

この問題は、TextAreaがスクローラーにある場合(またはソフトキーボードがアクティブになってTextAreaの位置を移動する場合)に発生します。

以下のコードをモバイルアプリケーションに追加すると、これを確認できます。

<s:Scroller width="100%" height="100%" top="100" bottom="100">
    <s:VGroup width="50%">
        <s:Button label="" height="600" width="440"/>
        <s:TextArea id="testing" />
        <s:TextArea id="testing2" />
        <s:Button label="" height="800" width="440"/>
    </s:VGroup>
</s:Scroller>

最初の画像は、テキストを含むアプリケーションです。

ここに画像の説明を入力してください

2番目の画像では、いくつか下にスクロールしました。下にスクロールすると、テキストが同じ場所に残っていることに注意してください(その上にあるボタンの上にあります)。

ここに画像の説明を入力してください

警告
ビューをスローすると、テキストはすぐに正しい場所(AIR Simulator上)に配置され、コンテンツが最終的な位置に落ち着くと再び正しく配置されます(モバイルデバイスでは、テキストは最後の休憩場所になるまで消えるように見えます) )。手動で押したり、ドラッグしたり、離したり(スローしない)したり、ソフトキーボードをアクティブにしたりしても発生しない何かがスロー時に発生しているため、これは朗報です。

残念ながら、テキストはスクローラーマスクを無視して他のすべてのコンテンツの上に表示される可能性がありますが、他の最初の問題が修正されれば、私はそれで生きることができます。

更新
幅を幅+1に設定すると、テキストを正しい位置に再配置できます。明らかにサイズを変更したくないため、これは機能しません。無効化しようとしましたが、何も機能していません。これがsoftKeyboardActivatingイベントで試したコードです。width = width + 1のコメントを外して、「機能する」ことを確認します。

    <s:TextArea id="testing" softKeyboardActivate="testing_softKeyboardActivateHandler(event)"/>

<fx:Script>
    <![CDATA[
        import mx.core.IInvalidating;
        protected function testing_softKeyboardActivateHandler(event:SoftKeyboardEvent):void {
            trace("Activating");
            /*testing.invalidateProperties();
            testing.invalidateDisplayList();
            testing.invalidateSize();
            testing.validateNow();
            parentGroup.validateNow();
            scroller.validateNow();*/
            // testing.invalidateParentSizeAndDisplayList();
            //IInvalidating(testing.parent).invalidateSize();
            //IInvalidating(testing.parent).invalidateDisplayList();
            //testing.width = NaN;
            //testing.width = testing.width+1;
        }
    ]]>
</fx:Script>

更新2
このコードは機能しますが、ハックであり、ビューがスローされたときにスクローラーが使用しているコードよりもはるかに低速です。

protected function testing_softKeyboardActivateHandler(event:SoftKeyboardEvent):void {
    StageTextAreaSkin2(testing.skin).styleChanged("styleName");
}

UPDATE 3
以下の回答セクションに回避策を追加しましたが、これはハックです。また、正しい位置にあると、正しくマスクされます。ですから、それも良いことです。しかし、私はまだこれを行う正しい方法を探しています。

これは、Flex 4.6、AIRSimulator上のMac上のAIR3.5、iPhone 5、およびAndroidNexus7でテストされています。

4

2 に答える 2

4

これは Flex のバグで、ネイティブ テキスト コントロールに関連しています。トップレベルのアプリケーションに以下を含めると、問題が解決します。

<fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";
        @namespace local "*";
        s|TextInput {
            skinClass: ClassReference("spark.skins.mobile.TextInputSkin");
            showPromptWhenFocused:false;
        }
        s|TextArea {
            skinClass: ClassReference("spark.skins.mobile.TextAreaSkin");
        }
</fx:Style>
于 2013-01-21T22:20:59.957 に答える
2

回避策は次のとおりです。MXMLファイルを作成し(通常はStageTextArea.mxmlで実行できます)、このコードをその中に配置します。

<?xml version="1.0" encoding="utf-8"?>
<s:TextArea xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark"
            softKeyboardActivate="softKeyboardActivateHandler(event)"
            softKeyboardDeactivate="softKeyboardDeactivateHandler(event)"
            added="addedHandler(event)" 
            removed="removedHandler(event)">

    <!-- USAGE 
        <controls:StageTextArea id="myTextArea" parentScroller="{myScroller}"/>
    -->

    <fx:Script>
        <![CDATA[
            import mx.events.PropertyChangeEvent;

            import spark.components.Scroller;

            private var _parentScroller:Scroller;

            public function get parentScroller():Scroller {
                return _parentScroller;
            }

            /**
             * Adds a listener to an ancestor scroller. 
             * */
            [Bindable]
            public function set parentScroller(value:Scroller):void {

                if (value && value.viewport) {
                    value.viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, handle, false, 0, true);
                }
                if (value==null && _parentScroller) {
                    value.viewport.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, handle);
                }
                _parentScroller = value;
            }


            /**
             * Add listener to parent component when added to the display list
             * */
            protected function addedHandler(event:Event):void {
                if (event.target==event.currentTarget) { 
                    // we could "discover" the scroller here if we wanted
                    // or we could just use parentScroller property
                    owner.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, handle, false, 0, true);
                }
            }

            /**
             * Remove listener to parent component when removed to the display list
             * */
            protected function removedHandler(event:Event):void {
                if (event.target==event.currentTarget) {
                    owner.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, handle);
                }
            }

            /**
             * Handle parent or ancestor scroll position changes
             */
            private function handle(e:PropertyChangeEvent):void {
                if (e.source == e.target && e.property == "verticalScrollPosition") {
                    //trace(e.property, "changed to", e.newValue);
                    updateTextFieldPosition();
                }
                if (e.source == e.target && e.property == "horizontalScrollPosition") {
                    //trace(e.property, "changed to", e.newValue);
                    updateTextFieldPosition();
                }
            }

            /**
             * Handles when keyboard activates
             * */
            protected function softKeyboardActivateHandler(event:SoftKeyboardEvent):void {
                updateTextFieldPosition();
            }

            /**
             * Handles when keyboard deactivates
             * */
            protected function softKeyboardDeactivateHandler(event:SoftKeyboardEvent):void {
                updateTextFieldPosition();
            }

            /**
             * Updates the native text fields position
             * */
            public function updateTextFieldPosition():void {
                skin.styleChanged("anything"); // force skin class to revalidate
            }

        ]]>
    </fx:Script>

</s:TextArea>
于 2013-01-21T02:09:46.817 に答える