web-dev-qa-db-ja.com

onEditorAction()のnullkeyeventおよびactionid = 0(Jelly Bean / Nexus 7)

アプリケーションの検索ボックスとして機能する編集テキストがあります。 Nexus 7のJellyBeanで、リッスンしているテキストボックスに何かを入力して押すと、KeyEvent = nullとActionId = 0がonEditorAction()メソッドに渡されます。他の誰かがこれに遭遇しましたか?バグかもしれないと思っています。

以下の2番目のifステートメントでは、actionId = 0およびKeyEvent = nullであるため、nullポインターを取得します。

// Search field logic.
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    Log.d(TAG, "onEditorAction");
    if (event != null && event.getAction() != KeyEvent.ACTION_DOWN)
        return false;
    if (actionId == EditorInfo.IME_ACTION_SEARCH
            || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
              .....Do some stuff();
     }
}
24
LowDev1

KeyEventのnullチェックを追加することになりました。これが3.0以降で発生することを指摘してくれたcommonswareに感謝します。解決策というよりは回避策のように見えますが、機能します。

// Search field logic.
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    Log.d(TAG, "onEditorAction");
    if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) {
        return false;
    } else if (actionId == EditorInfo.IME_ACTION_SEARCH
        || event == null
        || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
              .....Do some stuff();
    }
}
43
LowDev1

私の「バグのような振る舞い」は、imeActionLabelが複雑なことによるものであることがわかりました。 テキストフィールドガイド でカスタムリターンキーラベルを作成する方法として言及されているため、これを使用しただけです。これがロリポップでの私のテストの結果です、

ケース1:デフォルト、リターンキー記号=閉じ角かっこ

<EditText
    Android:singleLine="true"
    Android:inputType="textUri"/>

onEditorActionは1回呼び出されます。

  • KeyEvent = null、actionId = 5 = EditorInfo.IME_ACTION_NEXT
    • trueを返す場合、カーソルはEditTextに残り、キーボードopen
    • falseを返す場合、カーソルは次のフォーカス可能なものに移動、必要に応じてキーボードopen

ケース2:imeOptions、リターンキーシンボル=チェックマーク

<EditText
    Android:singleLine="true"
    Android:inputType="textUri"
    Android:imeOptions="actionDone"/>

onEditorActionは1回呼び出されます。

  • KeyEvent = null、actionId = 6 = EditorInfo.IME_ACTION_DONE
    • trueを返す場合、カーソルはEditTextに残り、キーボードopen
    • falseを返す場合、カーソルはEditTextに残り、キーボードは閉じます

ケース3:imeActionLabel、リターンキーシンボル= "URdone"

<EditText
    Android:singleLine="true"
    Android:inputType="textUri"
    Android:imeOptions="actionDone"
    Android:imeActionLabel="URdone"/>

onEditorActionは複数回呼び出すことができます。

  • KeyEvent = null、actionId = 0

    • trueを返す場合、カーソルはEditTextに残り、キーボードopen、onEditorActionは2回呼び出されません
    • falseを返す場合、onEditorActionは2番目の時間と呼ばれます。
  • KeyEvent = KeyEvent.ACTION_DOWN、actionId = 0

    • falseを返す場合、カーソルは次のフォーカス可能なものに移動、必要に応じてキーボードopen、onEditorActionは3回呼び出されません
    • trueを返す場合、onEditorActionは3回目と呼ばれます。
  • KeyEvent = KeyEvent.ACTION_UP、actionId = 0

    • trueを返す場合、カーソルはEditTextに残り、キーボードopen
    • falseを返す場合、カーソルは次のフォーカス可能なものに移動、必要に応じてキーボードopen

ノート:

ActionId = 0がEditorInfo.IME_ACTION_UNSPECIFIEDからのものかEditorInfo.IME_NULLからのものかわかりません。

次のフォーカス可能オブジェクトが編集不可能な場合、リターンキー記号は左向き矢印になります。

setOnFocusChangeListenerを使用してonFocusChangeをオーバーライドすることもできます。これは、上記のカーソルの動作に従って呼び出されます。

7
BeatriceThalo

KeyEvent.ACTION_UPの他に、KeyEvent.ACTION_DOWNもキャプチャする必要があります。 KeyEvent.ACTION_UPEditTextに渡されないため、onEditorActionが機能しない場合を除きます。例:

@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    final boolean isEnterEvent = event != null
            && event.getKeyCode() == KeyEvent.KEYCODE_ENTER;
    final boolean isEnterUpEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_UP;
    final boolean isEnterDownEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_DOWN;

    if (actionId == EditorInfo.IME_ACTION_DONE || isEnterUpEvent ) {
        // Do your action here
        performLogin();
        return true;
    } else if (isEnterDownEvent) {
        // Capture this event to receive ACTION_UP
        return true;
    } else {
        // We do not care on other actions
        return false;
    }
}

EditorInfo.IME_ACTION_DONEに従ってEditorInfo.IME_ACTION_のバージョンを修正するには、Android:imeOptions="actionNext"を置き換える必要があります。

3

[Enter]をクリックすると複数のイベントを取得できることに注意してください(Androidバージョンによって異なります)。1つはKeyDown(KeyEvent.ACTION_DOWN)用、もう1つはKeyUp用です。 (KeyEvent.ACTION_UP)。同じアクションに対して2つのサーバー呼び出しを誤って開始したことを確認するのを忘れたとき。

searchBox.setOnEditorActionListener(new OnEditorActionListener() {
// enter key in search box triggers search
@Override
public boolean onEditorAction(TextView v, int actionId,
        KeyEvent event) {
    if ((event != null && event.getAction() == KeyEvent.ACTION_UP) || event==null) {
        onSearchButtonClicked();
    }
    return true;
}
});
2
koljaTM

リターンキーをカスタマイズした場合、真実を発見することはできません。レイアウトにimeActionLabelimeActionIdの両方を設定する必要があります。といった:

imeActionLabel="xxxx"
imeActionId = "6"

あなたのJavaコード:

@Override
public boolean onEditorAction(TextView v, int actionId,  KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
     doSomeThing();
     return true;
   }

    return false;
}

それはうまくいくでしょう。

1
David Dai

すべてのenterイベントのアクションIDはデフォルトで0に設定されています。

Androidドキュメント から:

actionId int:アクションの識別子。これは、指定した識別子、またはEnterキーが押されたために呼び出された場合はEditorInfo#IME_NULLのいずれかになります。

したがって、Enterキーイベントを処理する適切な方法は次のとおりです。

@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_NULL) {
        // Handle return key here
        return true;
    }
    return false;
}
0
PouleyKetchoupp