ImeOptionsの完了ボタンのクリックをどのように処理しますか?


185

EditTextユーザーがEditTextをクリックしたときにキーボードの[完了]ボタンを表示できるように、次のプロパティを設定する場所があります。

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);

ユーザーが画面キーボードの完了ボタンをクリックすると(タイピングが終了しました)、RadioButton状態を変更したいと思います。

画面キーボードからヒットした完了ボタンをどのように追跡できますか?

ソフトウェアキーボードの右下の「完了」ボタンを示すスクリーンショット


1
OnKeyboardActionListenerは、コード例の助けになりますか?
d-man

回答:


210

私はロバーツとキラグスの答えの組み合わせで終わった:

((EditText)findViewById(R.id.search_field)).setOnEditorActionListener(
        new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        // Identifier of the action. This will be either the identifier you supplied,
        // or EditorInfo.IME_NULL if being called due to the enter key being pressed.
        if (actionId == EditorInfo.IME_ACTION_SEARCH
                || actionId == EditorInfo.IME_ACTION_DONE
                || event.getAction() == KeyEvent.ACTION_DOWN
                && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
            onSearchAction(v);
            return true;
        }
        // Return true if you have consumed the action, else false.
        return false;
    }
});

更新: 上記のコードは、コールバックを2回アクティブにすることがあります。代わりに、Googleチャットクライアントから取得した次のコードを選択しました。

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    // If triggered by an enter key, this is the event; otherwise, this is null.
    if (event != null) {
        // if shift key is down, then we want to insert the '\n' char in the TextView;
        // otherwise, the default action is to send the message.
        if (!event.isShiftPressed()) {
            if (isPreparedForSending()) {
                confirmSendMessageIfNeeded();
            }
            return true;
        }
        return false;
    }

    if (isPreparedForSending()) {
        confirmSendMessageIfNeeded();
    }
    return true;
}

4
IME_ACTION_DONEを探したところ、トリガーされないことに驚きました。ACTION_DOWNとKEYCODE_ENTERも探した後、ようやくonEditorAction()がトリガーされました。組み込みキーボードに違いはないので(Enterキーが強調表示されることを期待していました)、EditText XMLレイアウトにandroid:imeOptions = "actionSend"を使用するポイントは何なのかと思います。
誰かどこか

なぜこの答えは受け入れられないのですか?これはいくつかのケースで失敗しますか?
Archie.bpgc 2012

1
developer.android.com/reference/android/widget/…(「イベント」とは何かの説明は同じです)
Darpan

2
2番目のソリューションも2回トリガーされます。
Bagusflyer 2014

1
何がisPreparedForSending()、なぜ第二の方法が戻りますかtrue
CoolMind 2018年

122

これを試してください、それはあなたが必要とするもののために働くはずです:


editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
       //do here your stuff f
       return true;
    }
    return false;
    } 
});

10
これはHTC Evoでは機能しません。私が理解できる限り、HTCはimeOptionsを無視する独自のソフトキーボードを実装しました。
ダン

これで十分です(受け入れられた回答のように、イベントアクションやキーコードを確認する必要はありません)。NexusとSamsungのテストデバイスで動作します。
Jonik

安全のために、コードとビューのアクションが一致することを確認してください <EditText android:imeOptions="actionDone" android:inputType="text"/>
bh_earth0

40
<EditText android:imeOptions="actionDone"
          android:inputType="text"/>

Javaコードは次のとおりです。

edittext.setOnEditorActionListener(new OnEditorActionListener() { 
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            Log.i(TAG,"Here you can write the code");
            return true;
        }    
        return false;
    }
});

あなたはそれを処理したと言うためにif節でtrueを返す必要があります
Tim Kist 2017年

26

この質問が古いのはわかっていますが、何がうまくいったかを指摘したいと思います。

Android DevelopersのWebサイト(下に表示)のサンプルコードを使用しようとしましたが、機能しませんでした。EditorInfoクラスを確認したところ、IME_ACTION_SEND整数値が次のように指定されていることに気付きました。0x00000004

Androidデベロッパーのサンプルコード:

editTextEmail = (EditText) findViewById(R.id.editTextEmail);
editTextEmail
        .setOnEditorActionListener(new OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId,
                    KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    /* handle action here */
                    handled = true;
                }
                return handled;
            }
        });

そこで、整数値をres/values/integers.xmlファイルに追加しました。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="send">0x00000004</integer>
</resources>

次に、レイアウトファイルres/layouts/activity_home.xmlを次のように編集しました

<EditText android:id="@+id/editTextEmail"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:imeActionId="@integer/send"
  android:imeActionLabel="@+string/send_label"
  android:imeOptions="actionSend"
  android:inputType="textEmailAddress"/>

そして、サンプルコードは機能しました。


17

OnKeyListenerを設定し、[完了]ボタンをリッスンする方法の詳細。

まず、クラスのimplementsセクションにOnKeyListenerを追加します。次に、OnKeyListenerインターフェイスで定義された関数を追加します。

/*
 * Respond to soft keyboard events, look for the DONE press on the password field.
 */
public boolean onKey(View v, int keyCode, KeyEvent event)
{
    if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
        (keyCode == KeyEvent.KEYCODE_ENTER))
    {
        // Done pressed!  Do something here.
    }
    // Returning false allows other listeners to react to the press.
    return false;
}

EditTextオブジェクトが与えられた場合:

EditText textField = (EditText)findViewById(R.id.MyEditText);
textField.setOnKeyListener(this);

2
:あなたのOnKeyListenerは、もはやソフトキーイベントのために解雇されたので、これは、APIレベルを17+ターゲットとするアプリケーションに、それ以上動作しません developer.android.com/reference/android/text/method/...
JJB

彼らは今代替案を提案していますか?
Robert Hawkey

2
setOnEditorActionListenerを使用してEditorInfo.IME_ACTION_DONEを探すように切り替えましたが、これはうまく機能しているようです。
jjb 2013

onKeyはfalseではなくtrueを返す必要があります。
ラルフガブ2015年

16

ほとんどの人が質問に直接回答していますが、その背後にある概念について詳しく説明したいと思いました。最初に、デフォルトのログインアクティビティを作成したときに、IMEの注意に惹かれました。次のコードを含むコードが生成されました。

<EditText
  android:id="@+id/password"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/prompt_password"
  android:imeActionId="@+id/login"
  android:imeActionLabel="@string/action_sign_in_short"
  android:imeOptions="actionUnspecified"
  android:inputType="textPassword"
  android:maxLines="1"
  android:singleLine="true"/>

あなたはすでにinputType属性に精通している必要があります。これは、メールアドレス、パスワード、電話番号など、予想されるテキストのタイプをAndroidに通知するだけです。可能な値の完全なリストはここにあります

しかし、imeOptions="actionUnspecified"その目的がわからなかったのはそのためです。Androidでは、を使用してテキストを選択すると、画面の下部からポップアップするキーボードを操作できますInputMethodManager。キーボードの下隅にボタンがあり、現在のテキストフィールドに応じて、通常「次へ」または「完了」と表示されます。Androidでは、を使用してこれをカスタマイズできますandroid:imeOptions。「送信」ボタンまたは「次へ」ボタンを指定できます。完全なリストはここにあります

それによって、あなたがして定義することにより、アクションボタンを押圧するために聞くことができるTextView.OnEditorActionListenerためEditTextの要素。あなたの例のように:

editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(EditText v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
       //do here your stuff f
       return true;
    }
    return false;
    } 
});

今私の例では、android:imeOptions="actionUnspecified"属性がありました。これは、ユーザーがEnterキーを押したときにユーザーをログインさせたい場合に役立ちます。アクティビティで、このタグを検出してログインを試みることができます。

    mPasswordView = (EditText) findViewById(R.id.password);
    mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
            if (id == R.id.login || id == EditorInfo.IME_NULL) {
                attemptLogin();
                return true;
            }
            return false;
        }
    });

6

Kotlinのchikka.anddevAlex Cohnに感謝します

text.setOnEditorActionListener { v, actionId, event ->
    if (actionId == EditorInfo.IME_ACTION_DONE ||
        event?.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER) {
        doSomething()
        true
    } else {
        false
    }
}

ここEnterでは、のEditorInfo.IME_NULL代わりに返されるため、キーを確認しますIME_ACTION_DONE

Android imeOptions = "actionDone"が機能しないもご覧ください。に追加android:singleLine="true"しますEditText


6

Kotlinソリューション

Kotlinでそれを処理する基本的な方法は次のとおりです。

edittext.setOnEditorActionListener { _, actionId, _ ->
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        callback.invoke()
        true
    }
    false
}

Kotlin拡張

これを使用edittext.onDone{/*action*/}して、メインコードを呼び出すだけです。コードをはるかに読みやすく、保守しやすくします

fun EditText.onDone(callback: () -> Unit) {
    setOnEditorActionListener { _, actionId, _ ->
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            callback.invoke()
            true
        }
        false
    }
}

これらのオプションを編集テキストに追加することを忘れないでください

<EditText ...
    android:imeOptions="actionDone"
    android:inputType="text"/>

inputType="textMultiLine"サポートが必要な場合は、この投稿を読んでください


1
すばらしい回答です。共有していただきありがとうございます。setOnEditorActionListenerただし、の戻り値に関する糸くずの警告が表示され続けるようです。多分それはローカル構成設定の問題だけかもしれませんが、私のリンターは本当に(-blockではなく)リスナーのreturnステートメントとして「true」を受け入れるためにブランチも追加することを本当に望んでいます。elseif
dbm

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.