bug-a-lot による解決策は興味深いものです。優先順位を使用することは考えていませんでした。代わりに、イベント プロセスのさまざまなフェーズを利用しました。私にとっての問題は、矢印キーで特定のテキスト フィールド内の 1 文字を前進または後退させるか、フォーム内の次または前のフィールドにジャンプするかを決定することでした。
まず、キーのステージのイベント処理をオーバーライドします。
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);
各キーを 2 回処理することに注意してください。システムがウィザードリを実行する前に (事前入力は 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 が何をしたかを判断し、元に戻してから、何をすべきかを実行します。私の関数「typing」には、この議論には必要のないものがたくさんありますが、重要なことは 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 がユーザーに代わって何かを実行するという傾向を回避できるということです。