3

在我不知道如何解决的移动组件上使用 TextArea 和 TextInput 时,我遇到了两个问题。第一个是 TextArea 文本位置不正确,第二个是它与其他组件重叠。

当 TextArea 位于 Scroller 中(或软键盘激活并移动 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>

第一个图像是带有一些文本的应用程序。

在此处输入图像描述

在第二张图片中,我向下滚动了一些。当我向下滚动时,请注意文本仍保留在同一位置(它位于其上方按钮的顶部)!

在此处输入图像描述

CAVEAT
如果我抛出视图,那么文本会立即定位在正确的位置(在 AIR 模拟器上),并且在内容进入其最终位置时再次正确定位(在移动设备上,文本似乎会消失,直到它成为最终的静止位置)。这是一个好消息,因为在手动按下、拖动和释放(非投掷)或软键盘激活时不会发生投掷时发生的事情。

不幸的是,文本可能仍然出现在所有其他内容之上,而忽略了滚动条掩码,但如果另一个第一个问题得到解决,我可以忍受。

更新
如果我将宽度设置为宽度 + 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
此代码有效,但它是一个 hack,它比滚动视图在抛出视图时使用的代码慢得多:

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

更新 3
我在下面的答案部分添加了一个解决方法,但它是一个 hack。此外,当它处于正确位置时,它也被正确屏蔽。所以这也很好。但是,我仍在寻找正确的方法来做到这一点。

这已经在 AIR Simulator、iPhone 5 和 Android Nexus 7 上的 Mac 上使用 Flex 4.6、AIR 3.5 进行了测试。

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 回答