Wie gehe ich mit dem Klick auf die Schaltfläche "Fertig" von ImeOptions um?

185

Ich habe eine EditTextPosition , in der ich die folgende Eigenschaft einstelle, damit ich die Schaltfläche "Fertig" auf der Tastatur anzeigen kann, wenn der Benutzer auf den Text "Bearbeiten" klickt.

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);

Wenn der Benutzer auf der Bildschirmtastatur auf die Schaltfläche "Fertig" klickt (Eingabe beendet), möchte ich einen RadioButtonStatus ändern .

Wie kann ich die Schaltfläche "Fertig" verfolgen, wenn sie von der Bildschirmtastatur gedrückt wird?

Screenshot mit der Schaltfläche "Fertig" unten rechts auf der Softwaretastatur

D-Mann
quelle
1
kann mir OnKeyboardActionListener bei jedem Codebeispiel helfen ??
D-Mann

Antworten:

210

Am Ende hatte ich eine Kombination aus Roberts und Chirags Antworten:

((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;
    }
});

Update: Der obige Code würde den Rückruf manchmal zweimal aktivieren. Stattdessen habe ich mich für den folgenden Code entschieden, den ich von den Google Chat-Clients erhalten habe:

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;
}
Thomas Ahle
quelle
4
Ich habe gerade nach IME_ACTION_DONE gesucht und war überrascht, dass es nicht ausgelöst wurde. Nachdem ich auch nach ACTION_DOWN und KEYCODE_ENTER gesucht hatte, löste es schließlich onEditorAction () aus. Da ich keinen Unterschied in der eingebauten Tastatur sehe (ich habe erwartet, dass die Eingabetaste hervorgehoben wird), frage ich mich, wozu android: imeOptions = "actionSend" für das EditText-XML-Layout gut ist.
Jemand irgendwo
Warum wird diese Antwort nicht akzeptiert? scheitert dies in wenigen Fällen?
Archie.bpgc
1
developer.android.com/reference/android/widget/… (Beschreibung dessen, was ein "Ereignis" bestätigt).
Darpan
2
Die zweite Lösung wird ebenfalls zweimal ausgelöst.
Bagusflyer
1
Was ist isPreparedForSending()und warum gibt die zweite Methode zurück true?
CoolMind
122

Versuchen Sie dies, es sollte für das funktionieren, was Sie brauchen:


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;
    } 
});
chikka.anddev
quelle
10
Dies funktioniert nicht für HTC Evo. Soweit ich verstehen konnte, hat HTC eine eigene Softtastatur implementiert, die die imeOptions ignoriert.
Dan
Dies reicht aus (keine Notwendigkeit, die Ereignisaktion oder den Schlüsselcode wie in der akzeptierten Antwort zu betrachten); funktioniert auf meinen Nexus- und Samsung-Testgeräten.
Jonik
Um sicher zu gehen, stellen Sie sicher, dass die Aktion im Code und in der Ansicht übereinstimmt <EditText android:imeOptions="actionDone" android:inputType="text"/>
bh_earth0
40
<EditText android:imeOptions="actionDone"
          android:inputType="text"/>

Der Java-Code lautet:

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;
    }
});
Vinoj Vetha
quelle
Sie sollten true in der if-Klausel zurückgeben, um zu sagen, dass Sie damit umgegangen sind
Tim Kist
26

Ich weiß, dass diese Frage alt ist, aber ich möchte darauf hinweisen, was für mich funktioniert hat.

Ich habe versucht, den Beispielcode von der Android Developers-Website (siehe unten) zu verwenden, aber es hat nicht funktioniert. Also habe ich die EditorInfo-Klasse überprüft und festgestellt, dass der ganzzahlige Wert IME_ACTION_SEND als angegeben wurde 0x00000004.

Beispielcode von Android-Entwicklern:

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;
            }
        });

Also habe ich meiner res/values/integers.xmlDatei den ganzzahligen Wert hinzugefügt .

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

Dann habe ich meine Layoutdatei res/layouts/activity_home.xmlwie folgt bearbeitet

<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"/>

Und dann funktionierte der Beispielcode.

iRuth
quelle
17

Weitere Informationen zum Festlegen des OnKeyListener und zum Abhören der Schaltfläche Fertig.

Fügen Sie zuerst OnKeyListener zum Implementierungsabschnitt Ihrer Klasse hinzu. Fügen Sie dann die in der OnKeyListener-Oberfläche definierte Funktion hinzu:

/*
 * 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;
}

Gegeben ein EditText-Objekt:

EditText textField = (EditText)findViewById(R.id.MyEditText);
textField.setOnKeyListener(this);
Robert Hawkey
quelle
2
Dies funktioniert nicht mehr für Anwendungen, die auf API-Level 17+ abzielen, da Ihr OnKeyListener nicht mehr für Softkey-Ereignisse ausgelöst wird: developer.android.com/reference/android/text/method/…
jjb
Schlagen sie jetzt eine Alternative vor?
Robert Hawkey
2
Ich habe auf setOnEditorActionListener umgestellt, um nach EditorInfo.IME_ACTION_DONE zu suchen, was anscheinend gut funktioniert.
JJB
onKey sollte true und nicht false zurückgeben.
Ralphgabb
16

Während die meisten Leute die Frage direkt beantwortet haben, wollte ich mehr auf das Konzept dahinter eingehen. Zuerst wurde ich auf IME aufmerksam gemacht, als ich eine Standard-Anmeldeaktivität erstellte. Es wurde ein Code für mich generiert, der Folgendes enthielt:

<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"/>

Sie sollten bereits mit dem inputType-Attribut vertraut sein. Dies informiert Android lediglich über die Art des erwarteten Textes wie E-Mail-Adresse, Passwort oder Telefonnummer. Die vollständige Liste der möglichen Werte finden Sie hier .

Es war jedoch das Attribut, imeOptions="actionUnspecified"dass ich seinen Zweck nicht verstand. Mit Android können Sie mit der Tastatur interagieren, die am unteren Bildschirmrand angezeigt wird, wenn Text mit der Taste ausgewählt wird InputMethodManager. In der unteren Ecke der Tastatur befindet sich eine Schaltfläche mit der Aufschrift "Weiter" oder "Fertig", je nach aktuellem Textfeld. Mit Android können Sie dies mithilfe von anpassen android:imeOptions. Sie können eine Schaltfläche "Senden" oder "Weiter" angeben. Die vollständige Liste finden Sie hier .

Damit können Sie auf Drücken der Aktionstaste warten, indem Sie ein TextView.OnEditorActionListenerfür das EditTextElement definieren. Wie in Ihrem Beispiel:

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;
    } 
});

Jetzt in meinem Beispiel hatte ich android:imeOptions="actionUnspecified"Attribut. Dies ist nützlich, wenn Sie versuchen möchten, einen Benutzer anzumelden, wenn dieser die Eingabetaste drückt. In Ihrer Aktivität können Sie dieses Tag erkennen und dann versuchen, sich anzumelden:

    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;
        }
    });
Donato
quelle
6

Dank chikka.anddev und Alex Cohn in Kotlin ist es:

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
    }
}

Hier habe ich für den Check - EnterTaste, denn es gibt EditorInfo.IME_NULLstatt IME_ACTION_DONE.

Siehe auch Android imeOptions = "actionDone" funktioniert nicht . Fügen Sie android:singleLine="true"in der EditText.

CoolMind
quelle
6

Kotlin-Lösung

Die grundlegende Vorgehensweise in Kotlin ist:

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

Kotlin-Erweiterung

Verwenden Sie diese Option, um einfach edittext.onDone{/*action*/}Ihren Hauptcode einzugeben. Macht Ihren Code weitaus lesbarer und wartbarer

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

Vergessen Sie nicht, diese Optionen Ihrem Edittext hinzuzufügen

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

Wenn Sie inputType="textMultiLine"Unterstützung benötigen , lesen Sie diesen Beitrag

Gibolt
quelle
1
Tolle Antwort, danke fürs Teilen! Ich bekomme anscheinend immer wieder eine Flusenwarnung bezüglich des Rückgabewerts von setOnEditorActionListener. Vielleicht ist es nur eine Frage der lokalen Konfigurationseinstellungen, aber meine Linter wirklich, wirklich will , dass ich einen hinzufügen elseZweig zu , um die „wahre“ als return - Anweisung des Hörers (im Gegensatz zu dem akzeptieren if-Block).
dbm
0

Wenn Sie Android Annotations verwenden, https://github.com/androidannotations/androidannotations

Sie können die Annotation @EditorAction verwenden

@EditorAction(R.id.your_component_id)
void onDoneAction(EditText view, int actionId){
    if(actionId == EditorInfo.IME_ACTION_DONE){
        //Todo: Do your work or call a method
    }
}
Rafael Rocha
quelle