在移动组件上使用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 :
这段代码有效,但它是一个黑客,它比滚动器在抛出视图时使用的代码要慢得多:
protected function testing_softKeyboardActivateHandler(event:SoftKeyboardEvent):void {
StageTextAreaSkin2(testing.skin).styleChanged("styleName");
}
更新3
我在下面的答案部分添加了一个解决方法,但它是一个黑客。此外,当它处于正确的位置时,它也被正确掩盖。所以这也很好。但是,我仍然在寻找正确的方法来做到这一点。
这已经在AIR Sim Simulator,iPhone 5和Android Nexus 7上使用Flex 4.6,Mac上的AIR 3.5进行了测试。
答案 0 :(得分: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>
答案 1 :(得分: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>