2013-01-19 56 views
3

我在使用移動組件上的TextArea和TextInput時遇到了兩個問題,我不知道如何解決。第一個是TextArea文本沒有正確定位,第二個是它與其他組件重疊。在手機上Flex TextArea和TextInput未正確定位

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

第一個圖像是一些文本的應用程序。

enter image description here

在第二圖像,我向下滾動一些。正如我向下滾動注意到,文本保持在同一個位置(它位於上方的按鈕頂部)!

enter image description here

CAVEAT
如果我扔的觀點則文本將被立即放置在正確的位置(在AIR模擬器),並重新正確地定位在內容落戶到它的最終位置(在移動設備上文本似乎消失,直到它是最終安息的地方)。這是一個好消息,因爲在手動按下,拖動和釋放(不投擲)或軟鍵盤激活時不會發生丟擲事件。

不幸的是,文本可能仍然出現在所有其他內容的頂部,忽略了滾動條的掩碼,但如果其他第一個問題得到解決,我可以忍受這一點。

UPDATE
我能得到的文本在合適的位置重新定位,如果我設置寬度爲寬度+ 1,這是行不通的,因爲我不想明顯調整其大小。我試圖無效,沒有任何工作。這是我在softKeyboardActivating事件中嘗試的代碼。取消註釋出寬度=寬度+ 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"); 
} 

更新3
我已在下面的答案部分的方法,但它是一個黑客。而且,當它處於正確的位置時,它也被正確屏蔽。所以這也很好。不過,我仍然在尋找正確的方法來做到這一點。

這已被使用Flex 4.6,在Mac AIR 3.5對AIR模擬器,iPhone 5和Android的Nexus 7.

回答

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

這是Flex中的一個bug,與原生文本控件相關。 如果在頂級應用程序中包含以下內容,它可以解決問題:

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