在手机上Flex TextArea和TextInput无法正确定位 [英] Flex TextArea and TextInput on mobile not positioning correctly

查看:187
本文介绍了在手机上Flex TextArea和TextInput无法正确定位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

当TextArea位于Scroller中时(或者软键盘激活并移动TextArea位置),就会出现问题。



如果您将以下代码添加到移动应用程序中,您可以看到这一点:

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

第一张图片是带有一些文字的应用程序。





在第二张图片中,我滚动了一些图片。正如我向下滚动注意到,文本保持在同一个地方(它是在上面的按钮的顶部)!





CAVEAT : >
如果我抛出视图,那么文本立即被放置在正确的位置(在AIR模拟器上),并在内容定位到其最终位置时再次正确定位(在移动设备上,文本似乎消失,直到它最后的安息之地)。这是一个好消息,因为手动按压,拖动和释放(而不是抛出)或在软键盘激活时不会发生抛出的事情。



不幸的是,文本可能仍然会出现在所有其他内容的顶部忽略滚动面具,但我可以忍受,如果其他第一个问题是固定的。
$ b

更新

如果将宽度设置为宽度,我可以将文本重定位到正确的位置。这是不行的,因为我不想调整它的大小。我试图无效,没有任何工作。这是我在softKeyboardActivating事件中尝试的代码。取消注释width = width + 1以查看它work:

 < s:TextArea id =testingsoftKeyboardActivate = testing_softKeyboardActivateHandler(事件)/> 

< 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

这是一个黑客,它比滚动使用视图时所使用的代码慢得多:

$ p $ 受保护的函数testing_softKeyboardActivateHandler(event :SoftKeyboardEvent):void {
StageTextAreaSkin2(testing.skin).styleChanged(styleName);

更新3

我已经在下面的答案部分添加了一个解决方法,但它是一个黑客。而且,当它处于正确的位置时,它也被正确地掩盖了。所以这也很好。不过,我仍然在寻找正确的方法来做到这一点。


这已经在AIR Simulator,iPhone 5和Android Nexus 7上的Flex 4.6,AIR 3.5上测试过。

解决方案

这是一个解决方法。创建一个MXML文件(通常StageTextArea.mxml将会这样做)并将其放置在其中。

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

<! - USAGE
< controls:StageTextArea id =myTextAreaparentScroller ={myScroller}/>
- >

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

导入spark.components.Scroller;

private var _parentScroller:Scroller;

public function get parentScroller():Scroller {
return _parentScroller;
}
$ b $ / **
*向一个祖先滚动器添加一个监听器。
* /
[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;


$ b / **
*当添加到显示列表时,将监听器添加到父组件
* * /
protected function addedHandler (event:Event):void {
if(event.target == event.currentTarget){
//如果我们需要
//我们可以在这里发现滚动条只需使用parentScroller属性
owner.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handle,false,0,true);


$ **
*当移除到显示列表时,将监听器移除到父组件
* * /
protected function removedHandler(event:Event):void {
if(event.target == event.currentTarget){
owner.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,handle);


$ b $ **
处理父级或祖先滚动位置变化

私有函数句柄(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 ==horizo​​ntalScrollPosition){
//trace(e.property,changed to, e.newValue);
updateTextFieldPosition();


$ **
*当键盘激活时处理
* * /
保护功能softKeyboardActivateHandler(event:SoftKeyboardEvent): void {
updateTextFieldPosition();

$ b $ ** b $ b *当键盘停用时处理
* * /
保护功能softKeyboardDeactivateHandler(事件:SoftKeyboardEvent):void {
updateTextFieldPosition();

$ b $ ** b $ b *更新本地文本字段位置
* /
public function updateTextFieldPosition():void {
skin.styleChanged( 东西); //强制皮肤类来重新验证
}

]]>
< / fx:Script>

< / s:TextArea>


I've had two issues when working with TextArea and TextInput on mobile components I don't know how to solve. The first is that the TextArea text does not position correctly and the second is that it overlaps other components.

The issues occur when the TextArea is in a Scroller (or the soft keyboard activates and moves the TextArea position).

You can see this if you add the code below to a mobile Application:

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

The first image is the application with some text.

In the second image I've scrolled down some. As I've scrolled down notice that the text has remained in the same place (it's on top of the button that was above it)!

CAVEAT:
If I throw the view then the text is immediately positioned in the correct place (on the AIR Simulator) and is positioned again correctly when the content settles into it's final position (on mobile devices the text seems to disappear until it's final resting place). This is good news since something is happening on throw that is not happening when manually pressing, dragging and releasing (not throwing) or on soft keyboard activating.

Unfortunately, the text may still appears on top of all other content ignoring the scrollers mask but I can live with that if the other first problem is fixed.

UPDATE
I can get the text to reposition in the right position if I set the width to a width + 1. This is not going to work because I don't want to resize it obviously. I tried invalidating and nothing is working. Here is the code I tried in the softKeyboardActivating event. Uncomment out the width = width+1 to see it "work" :

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

UPDATE 2:
This code works but it's a hack and it's much slower than the code that the scroller is using when the view is thrown:

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

UPDATE 3
I've added a workaround in the answers section below but it is a hack. Also, when it's in the right position it also is correctly masked. So that's good as well. However, I'm still looking for the right way to do this.

This has been tested with Flex 4.6, AIR 3.5 on Mac on the AIR Simulator, iPhone 5 and Android Nexus 7.

解决方案

Here is a workaround. Create an MXML file (usually StageTextArea.mxml will do) and place this code in it.

<?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>

这篇关于在手机上Flex TextArea和TextInput无法正确定位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆