Интригующее решение очень интересное - я не думал использовать приоритеты. Вместо этого я использовал различные фазы процесса события. Для меня проблема заключалась в том, чтобы решить, должны ли клавиши со стрелками перемещаться вперед или отступать на один символ в данном текстовом поле, или переходить к следующему или предыдущему полю в форме.
Сначала я переопределяю обработку событий на сцене для ключей:
stage.addEventListener(KeyboardEvent.KEY_UP, typing);
// Sneak in before the normal processing handles right and left arrow keystrokes.
stage.addEventListener(KeyboardEvent.KEY_DOWN, pretyping, true, 10);
Обратите внимание, что я буду обрабатывать каждую клавишу дважды - до того, как система выполнит свое волшебство (предварительный набор вызывается до KEY_DOWN), поэтому я могу видеть, где находится курсор, до того, как Flash перемещает его, и после того, как система его обработает (набрав, после KEY_UP).
/** Capture prior state of text field so we can later tell if user should tab to next field or previous field. */
private function pretyping(evt:KeyboardEvent):void {
var keyString:String = Configuration.getKeyString(evt);
if (isFocusInTextBox()) {
var tf:TextField = getFocus() as TextField;
capturePhaseCaret = tf.caretIndex;
}
}
getKeyString - мой метод - все, что он делает, это превращает эти коды в удобную мнемонику. И isFocusInTextBox - это вызов моего менеджера фокуса - я заменил стандартный менеджер фокуса, чтобы преодолеть другие проблемы с Flash. Мне просто нужно знать, если это текстовое поле или нет.
Затем я должен обработать ключ после того, как Flash уже переместил курсор и, возможно, даже перешел на новое поле, и, взглянув на предыдущее состояние, решить, что сделал Flash, отменить его и затем сделать то, что должно произойти. В моей функции «печатать» есть много вещей, которые не нужны для этого обсуждения, но важно то, что она вызывает allowKeyMapping. allowKeyMapping решает, ввел ли пользователь стрелку вперед (или стрелку вниз) из последней позиции символа в текстовом поле, или ввел стрелку назад с начала. Если это так, «печатать» будет переход к следующему или предыдущему полю, соответственно.
/** Prefer default behavior and do not allow certain kestrokes to be reinterpreted by key mappings, such as left and right cursor keys in text boxes. */
private function allowKeyMapping(keyString:String) {
var allow:Boolean;
// If focus is in a text field, allow right arrow to advance to next field only if caret is at end of text.
// Conversely, allow left arrow to back up to previous field only if caret is at beginning of text.
// The trick is that the normal processing of keystrokes by TextFields occurs before this method is called,
// so we need to know the caret position from before the key was pressed, which we have stored in capturePhaseCaret, set in pretyping.
if (isDragging) {
allow = false;
}
else if (isFocusInTextBox()) {
var tf:TextField = getFocus() as TextField;
if (keyString == Configuration.LEFT_CURSOR_KEY) {
allow = tf.caretIndex == 0 && capturePhaseCaret == 0;
}
else if (keyString == Configuration.RIGHT_CURSOR_KEY) {
allow = tf.caretIndex == tf.text.length && capturePhaseCaret == tf.text.length;
}
else {
allow = true;
}
}
else {
allow = true;
}
return allow;
}
Извините, у меня нет подготовленного компактного примера. Я просто подумал, что важно подчеркнуть, что вы можете обойти склонность Flash к тому, чтобы делать что-то для вас, хотите ли вы, чтобы это произошло или нет.