Flex TextInput с мобильными оболочками по умолчанию автоматически восстанавливает фокус при закрытии выноски - PullRequest
0 голосов
/ 20 февраля 2012

Я работаю над простой функцией автозаполнения для моего мобильного приложения Flex. Для этого у меня есть CalloutButton, который запускает Callout. Выноска содержит несколько списков, из которых пользователь может выбирать элементы. При выборе элемента сноска закрывается (calloutButton.closeDropDown ()).

То же самое поведение сделано для TextInput. Пользователь вводит текст, открывается выноска, и в соответствии с введенным текстом списки меняются. Пока работает нормально. Теперь, когда пользователь выбирает элемент из любого из списков, выноска закрывается. Тоже все в порядке. Теперь проблема после закрытия выноски, TextInput автоматически восстанавливает фокус.

На мобильном устройстве это более чем тревожно.

Я ограничил это поведение мобильным скином TextInput (spark.skins.mobile.TextInputSkin), поскольку TextInput без этого класса скина не отображает это поведение.

Теперь вы можете сказать, что вместо этого используйте скин по умолчанию, но, к сожалению, я не могу. Скин по умолчанию имеет ошибку на устройствах Android, которая не проходит через событие ввода. С этим я мог бы смириться, поскольку я не обязательно зависел от события ввода, однако, скин Spark Mobile позволяет продолжать вводить текст в TextInput даже после открытия выноски, что крайне необходимо, так как списки меняются в соответствии с введенный текст.

Я не могу предоставить какой-либо код, так как проблема была сужена до skinClass, поэтому не должно быть в моем собственном коде. Поверьте, я попробовал все приятные и не очень приятные методы, чтобы предотвратить фокусировку TextInput, но ничего не получалось.

Итак, я застрял здесь! Надеюсь, у вас, ребята, есть идеи, как это решить.

Edit: Ниже приведены шаги поведения моего приложения. (чтобы быть справедливым, рабочий процесс внутри выноски немного сложнее, я работаю с несколькими списками и SplitViewNavigator здесь (таким образом, я не могу использовать автозаполнение Flextras), но это не влияет на проблему фокуса TextInput I ' м лицом).

  • Ввести текст в TextInput
  • При смене ключа открывается выноска с двумя списками.
  • Первый список получает результаты в соответствии с введенным текстом из веб-службы
  • Пользователь выбирает элемент из списка
  • Второй список получает результаты в соответствии с выбором из первого списка из веб-службы
  • Пользователь выбирает элемент во втором списке
  • Callout закрывается

Это все работает нормально, за исключением того, что TextInput получает фокус после закрытия Callout. Я действительно не знаю, что вызывает это поведение.

Edit2: код для дальнейшей иллюстрации проблемы. Естественно, это урезано до самых основ, но оно отражает поведение компонента и фокус.

Сначала CalloutButton и TextInput, которые оба могут управлять Callout:

<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);
}

Примечание: 'val' (текст TextInput) обрезается и еще много чего, в конечном итоге это приведет к массиву строк, представленных как _searchSyms.

Далее перечислены следующие 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 является пустой строкой:

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 вынужден закрываться, и функция поиска, которая передает значение компоненту (еще не вставлен здесь, наберитесь терпения;), получает значение элемента.По сути, это выглядит так (не говоря уже о материалах 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.Как уже было сказано, эта функция в основном передает только отформатированное значение поиска выбранному компоненту.Это происходило либо при «Вводе» TextInput (как показывает приведенный выше код), либо при выборе элемента из одного из списков выноски.

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 получит его.Я понятия не имею, где и почему это происходит, и мне нужно как можно быстрее избавиться от этого поведения!

Ого, что за пост, кто-нибудь еще читает это?;) Ну, я на это надеюсь.

1 Ответ

0 голосов
/ 22 февраля 2012

Ну, после нескольких часов тестирования нескольких способов предотвратить автоматическое получение фокуса TextInput, я (вроде) решил проблему, хотя я думаю, что это более грязный взлом, чем что-либо еще.

Установка focusEnabled TextInputfalse работает нормально, хотя указание фокуса (граница вокруг TextInput) больше не будет работать с этим (проблема, с которой я могу сейчас жить).

Тем не менее, я бы очень хотел знать,что именно здесь происходит, особенно в классе мобильных тем.

...