アプリケーションの検索ボックスとして機能する編集テキストがあります。 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();
}
}
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();
}
}
私の「バグのような振る舞い」は、imeActionLabel
が複雑なことによるものであることがわかりました。 テキストフィールドガイド でカスタムリターンキーラベルを作成する方法として言及されているため、これを使用しただけです。これがロリポップでの私のテストの結果です、
ケース1:デフォルト、リターンキー記号=閉じ角かっこ
<EditText
Android:singleLine="true"
Android:inputType="textUri"/>
onEditorActionは1回呼び出されます。
EditorInfo.IME_ACTION_NEXT
ケース2:imeOptions
、リターンキーシンボル=チェックマーク
<EditText
Android:singleLine="true"
Android:inputType="textUri"
Android:imeOptions="actionDone"/>
onEditorActionは1回呼び出されます。
EditorInfo.IME_ACTION_DONE
ケース3:imeActionLabel
、リターンキーシンボル= "URdone"
<EditText
Android:singleLine="true"
Android:inputType="textUri"
Android:imeOptions="actionDone"
Android:imeActionLabel="URdone"/>
onEditorActionは複数回呼び出すことができます。
KeyEvent = null、actionId = 0
KeyEvent = KeyEvent.ACTION_DOWN
、actionId = 0
KeyEvent = KeyEvent.ACTION_UP
、actionId = 0
ノート:
ActionId = 0がEditorInfo.IME_ACTION_UNSPECIFIED
からのものかEditorInfo.IME_NULL
からのものかわかりません。
次のフォーカス可能オブジェクトが編集不可能な場合、リターンキー記号は左向き矢印になります。
setOnFocusChangeListener
を使用してonFocusChange
をオーバーライドすることもできます。これは、上記のカーソルの動作に従って呼び出されます。
KeyEvent.ACTION_UP
の他に、KeyEvent.ACTION_DOWN
もキャプチャする必要があります。 KeyEvent.ACTION_UP
がEditText
に渡されないため、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"
を置き換える必要があります。
[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;
}
});
リターンキーをカスタマイズした場合、真実を発見することはできません。レイアウトにimeActionLabelとimeActionIdの両方を設定する必要があります。といった:
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;
}
それはうまくいくでしょう。
すべての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;
}