我正在为我的Flex移动应用程序开发一个简单的自动完成功能。为此,我有一个触发Callout的CalloutButton。 标注包含一些列表,用户可以从中选择项目。在项目选择上,标注将被关闭(calloutButton.closeDropDown())。
TextInput的行为完全相同。用户输入文本,打开标注,并根据输入的文本更改列表。到目前为止工作正常。现在,当用户从任何列表中选择项目时,标注将关闭。还好。 现在问题是,在标注关闭后,TextInput会自动重新获得焦点。
在移动设备上,这不仅令人不安。
我将此行为缩小到移动TextInput外观(spark.skins.mobile.TextInputSkin),因为没有此外观类的TextInput不会显示此行为。
现在你可能会说只使用默认皮肤但不幸的是我不能。默认外观有一个Android设备的错误,它不会通过enter事件传递。我可以忍受,因为我不一定依赖于enter事件,但是,即使在打开标注之后,spark移动皮肤也允许继续在TextInput中输入文本,这在列表更改时非常需要根据输入的文字。
我无法提供任何代码,因为问题已缩小到skinClass,因此不应该在我自己的代码中。相信我,我尝试了所有好的,不太好的方法来阻止TextInput再次获得焦点,但没有任何效果。
所以,完全停留在这里! 希望你们对如何解决这个问题有一些想法。
编辑: 下面是我的应用程序的行为步骤。 (公平地说,标注内部的工作流程稍微复杂一些,我在这里使用了几个列表和一个SplitViewNavigator(因此无法使用Flextras自动完成),但这不会影响我面临的TextInput焦点问题。
这一切都正常,除了TextInput在Callout关闭后获得焦点。 我真的不知道是什么引发了这种行为。
Edit2:代码以进一步说明问题。 当然,这被简化为基础,但它反映了组件的行为和焦点。
首先可以控制Callout的CalloutButton和TextInput:
<ui:SearchCallout id="detailSearch"/>
<s:TextInput id="searchInput" skinClass="spark.skins.mobile.TextInputSkin"
enter="historySearch(searchInput.text)"
focusOut="searchFocusOutEvent(event)"
focusIn="searchFocusInEvent(event)"/>
TextInput的焦点处理程序不会执行与标注相关的任何操作,它们只是设置了另一个组件的当前状态,因此我将其留在此处。
函数historySearch关闭CallOut(我强制它关闭,因为它不会与通常的closeDropDown()关闭),格式化搜索文本,处理searchHistory并最终触发传递格式化搜索文本的搜索功能到选定的组件。 以下是对此案件至关重要的部分:
private function historySearch(val:String):void {
detailSearch.forceClose=true;
detailSearch.closeDropDown();
searchEvent(_searchSyms, true);
}
注意:&#39; val&#39; (TextInput&#39; s文本)被修剪,以及最终它将导致一个字符串数组,由&#39; _searchSyms&#39;表示。
进一步的eventListeners如下:
searchInput.addEventListener(KeyboardEvent.KEY_DOWN, onKeyEvent);
searchInput.addEventListener(FlexEvent.VALUE_COMMIT, onKeyEvent);
searchInput.addEventListener(TextOperationEvent.CHANGE, onTextChange);
KEY_DOWN和VALUE_COMMIT与Callout无关,它们用于处理searchHistory的内容,因此我会在这里留下onKeyEvent函数。
onTextChange触发服务器上的字符串搜索,并在TextInput的文本为空字符串时关闭Callout:
private function onTextChange(event:Event):void {
if(searchInput.text=="") {
if(detailSearch.isDropDownOpen) {
(detailSearch.rightView.activeView as RightView).clearDetailList();
detailSearch.isCloseable=true;
}
}
_searchManager.getRicsByChar(searchInput.text);
}
最终服务器将响应并传递一组响应。标注将被打开,其列表中会显示响应。
我不会在这里粘贴所有Callout内容的代码,因为它太多了。基本上,用户从任何列表中选择一个项目,Callout被强制关闭,并且将值传递给组件的搜索功能(此处尚未粘贴,耐心;)被赋予项目的值。这基本上看起来像这样(更不用说FlexGlobals的东西了,一旦焦点问题得到解决,这一切都会被重构):
var search:String = String(event.currentTarget.selectedItem);
FlexGlobals.topLevelApplication.detailSearch.forceClose=true;
FlexGlobals.topLevelApplication.detailSearch.closeDropDown();
FlexGlobals.topLevelApplication.searchEvent(new Array(search), true);
好吧,现在是整个功能的最后一步,即searchEvent。如前所述,此功能基本上只将格式化的搜索值传递给所选组件。这要么发生在&#39; Enter&#39; of TextInput(如上面的代码所示),或者从其中一个Callout列表中选择一个项目。
public function searchEvent(_searchSymbols:Array, setText:Boolean):void {
if(setText) {
var _searchString:String="";
for each (var _sym:String in _searchSymbols) {
_searchString += _sym + ", ";
}
searchInput.text = _searchString.substring(0, _searchString.length-2);
}
stage.focus=null;
if(selectedWindowContainer) {
// set the array of search items to the selected component here
selectedWindowContainer.setFocus();
} else
trace("[MAIN] no component selected");
}
基本上就是这样。此功能是我的搜索例程的最后一步,所选组件(将获取搜索项)正在获得焦点。 然而,它会再次自动失去焦点,TextInput会收到它。我不知道在哪里以及为什么会发生这种情况,我需要尽快摆脱这种行为!
哇,什么帖子,还有人还在读这个吗? ;)好吧,我希望如此。答案 0 :(得分:0)
好吧,经过几个小时的测试来阻止TextInput自动获得焦点,我(有点)解决了这个问题,虽然我认为它比其他任何东西都更糟糕。
将TextInput的focusEnabled设置为false可以正常工作,即使焦点指示(TextInput周围的边框)不再适用于此(我现在可以解决的一个问题)。
不过,我真的很想知道这里到底发生了什么,特别是在移动皮肤课上。