Mehrzeiliger EditText mit fertigem SoftInput-Aktionsetikett auf 2.3

82

Gibt es eine Möglichkeit, ein Multi-Line- EditTextGerät zu haben und das IME-Aktionslabel "Done" unter Android 2.3 zu verwenden?

In Android 2.2 ist dies kein Problem. Die Eingabetaste zeigt die IME-Aktionsbezeichnung "Fertig" ( android:imeActionLabel="actionDone") an und schließt die Soft-Eingabe, wenn Sie darauf klicken.

Bei der Konfiguration eines EditTextfür mehrere Zeilen entfernt entfernt Android 2.3 die Möglichkeit, die Aktion "Fertig" für die Soft Input-Tastatur anzuzeigen.

Ich habe es geschafft, das Verhalten der Soft Input-Eingabetaste mit einem zu ändern KeyListener, aber die Eingabetaste sieht immer noch wie eine Eingabetaste aus.


Hier ist die Erklärung der EditText

<EditText
        android:id="@+id/Comment"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="0dp"
        android:lines="3"
        android:maxLines="3"
        android:minLines="3"
        android:maxLength="60"
        android:scrollHorizontally="false"
        android:hint="hint"
        android:gravity="top|left"
        android:textColor="#888"
        android:textSize="14dp"
        />
<!-- android:inputType="text" will kill the multiline on 2.3! -->
<!-- android:imeOptions="actionDone" switches to a "t9" like soft input -->

Wenn ich den inputTypeWert nach dem Laden überprüfe und die Inhaltsansicht in der Aktivität einstelle, wird Folgendes angezeigt:

inputType = 0x20001

Welches ist:

  • Klasse = TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_NORMAL
  • flags = InputType.TYPE_TEXT_FLAG_MULTI_LINE
Ohhorob
quelle

Antworten:

163

Nun, nach dem erneuten Lesen von TextViewund EditorInfodocs ist klar geworden, dass die Plattform IME_FLAG_NO_ENTER_ACTIONmehrzeilige Textansichten erzwingen wird .

Beachten Sie, dass TextViewdieses Flag in mehrzeiligen Textansichten automatisch für Sie gesetzt wird.

Meine Lösung besteht darin, EditTextdie IME-Optionen zu unterklassifizieren und anzupassen, nachdem die Plattform sie konfiguriert hat:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    InputConnection connection = super.onCreateInputConnection(outAttrs);
    int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
    if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
        // clear the existing action
        outAttrs.imeOptions ^= imeActions;
        // set the DONE action
        outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
    }
    if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
        outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
    }
    return connection;
}

Oben erzwinge ich IME_ACTION_DONEauch, obwohl dies durch langwierige Layoutkonfiguration erreicht werden kann.

Ohhorob
quelle
24
Normalerweise gebe ich keine generischen Kommentare wie "omg danke", aber diese Antwort war ausreichend hilfreich und unbeachtet, so dass ich dachte, sie hätte Anerkennung verdient. Zusammenfassend omg danke. :-)
Pflüger
3
+1 für die Antwort, aber wenn Sie in diesem Fall einen Eingabetyp für einen Edittext aus Code festlegen. Es entfernt die vertikale Schriftrolle und fügt eine horizontale Schriftrolle hinzu. Um dieses Problem zu lösen, verwenden Sie den folgenden Code. editTextObj.setInputType (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE); Kann im Allgemeinen passieren, wenn Sie eine Ansicht wiederverwenden, indem Sie dieselbe in mehrere Layouts aufnehmen. @ohhorob vielen danke für die lösung.
Jayshil Dave
2
Es wirkt wie ein Zauber! Aber ich verstehe den Code nicht wirklich. Hast du einen Ort, an dem ich über den gesamten Flaggenmechanismus lesen kann?
Vanleeuwenbram
Danke, ich bin ein Anfänger. Ich habe dies in meine Aktivität eingefügt, die ein Dialogfeld verwendet EditText, sodass es nicht in meiner Aktivitäts-XML enthalten ist. Ich habe versucht, diesen Code in meine Aktivität einzufügen, habe aber eine Fehlermeldung erhalten : The method onCreateInputConnection(EditorInfo) of type SMSMain must override or implement a supertype method. Sie rufen superam Anfang an, sind sich also nicht sicher, wo das Problem liegt. Sie haben Vorschläge? Vielen Dank.
Azurespot
@NoniA. Sie müssen eine Unterklasse von EditText erstellen. und in dieser Klasse müssen Sie diese Methode aufrufen. Erstellen Sie eine Klasse, die sich auf EditText erstreckt. und setzen Sie diese Methode in diese Klasse.
Shah
103

Ohhorobs Antwort ist im Grunde richtig, aber sein Code ist wirklich wirklich überflüssig! Es entspricht im Grunde dieser viel einfacheren Version (vollständiger Code für faule Leser):

package com.example.views;

import android.content.Context;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;

// An EditText that lets you use actions ("Done", "Go", etc.) on multi-line edits.
public class ActionEditText extends EditText
{
    public ActionEditText(Context context)
    {
        super(context);
    }

    public ActionEditText(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public ActionEditText(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs)
    {
        InputConnection conn = super.onCreateInputConnection(outAttrs);
        outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        return conn;
    }
}

Beachten Sie, dass einige inputTypeOptionen wie textShortMessagedies nicht funktionieren! Ich schlage vor, Sie beginnen mit inputType="text". So können Sie es in Ihrem XML verwenden.

<com.example.views.ActionEditText
    android:id=...
    android:layout_stuff=...
    android:imeOptions="actionDone"
    android:inputType="textAutoCorrect|textCapSentences|textMultiLine"
    android:maxLines="3" />
Timmmm
quelle
Timmmm, ist das auf 2.3 getestet?
Ohhorob
1
Wenn Ihr Code unter 2.3 funktioniert, sollte dies auch bei mir der Fall sein. Sie sind fast gleich, und ich habe meinen oder Ihren Code verwendet, also danke! Gibt es Besonderheiten von 2.3, die nicht in 4.0 enthalten sind? Der Standard "Keine Aktionen bei mehrzeiligen Bearbeitungen" ist bewusstes Verhalten, das von Google hinzugefügt wurde.
Timmmm
5
Ich habe dies auf 2.3 (und 4.x) versucht und es hat für meine Anwendung funktioniert.
mlc
2
@ matej.smitala Ja, du kannst nicht beides haben.
Timmmm
1
Nach stundenlanger Suche nach der besten Lösung scheint dies der beste und einfachste Weg zu sein, einen mehrzeiligen Bearbeitungstext ohne die Eingabetaste zu erzielen.
Micnguyen
56

Eine alternative Lösung zur Unterklasse der EditText-Klasse besteht darin, Ihre EditText-Instanz folgendermaßen zu konfigurieren:

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

Zumindest funktioniert das bei mir unter Android 4.0. Es konfiguriert die EditText-Instanz so, dass der Benutzer eine einzeilige Zeichenfolge bearbeitet, die mit Soft-Wrapping in mehreren Zeilen angezeigt wird, selbst wenn eine IME-Aktion festgelegt ist.

Futzilogik
quelle
2
@Futzilogik: Sie, Sir, verdienen viel mehr Stimmen! Diese Antwort war ein Lebensretter und auch eine einfache. Ich meine, omg wow. Ich wünschte, ich könnte mehr als einmal abstimmen. Vielen Dank!
Swayam
3
Ich verwende 4.4.2, und das hat bei mir oder zumindest auf meine Art nicht funktioniert. Ich habe es nur in XML gemacht, also ist das vielleicht ein Problem. Ich habe den inputType auf "textEmailAddress | textMultiLine", scrollHorizontally auf false, maxLines auf 500 (XML-Datei), singleLine auf false und imeOptions auf actionNext konfiguriert. Ich habe versucht, "textMultiLine" aus dem Eingabetyp zu entfernen. Mit textMultiLine erhalte ich die EINGABETASTE auf der Tastatur, und ohne sie bleibt alles in einer einzigen Zeile und scrollt immer noch horizontal. Dies schien die einfachste Lösung zu sein, aber die obige funktioniert für mich, also machen Sie es erst einmal.
reaktiver Kern
6
In Bezug auf meinen vorherigen Kommentar (der nicht bearbeitet werden konnte), den Verdacht, dass es sich entweder um ein Problem handelte, bei dem MAX_VALUE nicht festgelegt wurde, oder um diese nur zu ändern, nachdem der Edittext erstellt wurde, habe ich versucht, den hier angegebenen Code einzugeben, und es funktioniert! Ich wollte nur für andere posten, du kannst es nicht in XML machen (oder ich konnte es sowieso nicht). Andere Einstellungen, die ich habe: singleLine = false, imeOptions = actionNext, inputType = textEmailAddress (keine mehrzeilige).
reaktiver Kern
funktioniert sehr gut. Dies ist ein gutes Beispiel für die Verbesserung einer alten Antwort!
nPn
Ich arbeite für mich an einem Galaxy S5 mit Lollipop. Tolle Lösung. Seltsam, dass das horizontale Scrollen in XML nicht den gleichen Effekt hat
Scott Birksted,
7

Nach vorheriger Antwort

public class MultiLineText extends EditText {

    public MultiLineText(Context context) {
        super(context);
    }

    public MultiLineText(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public MultiLineText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnection connection = super.onCreateInputConnection(outAttrs);
        int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
        if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
            // clear the existing action
            outAttrs.imeOptions ^= imeActions;
            // set the DONE action
            outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
        }
        if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
            outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        }
        return connection;
    }
}

Verwenden Sie dies wie

<myapp.commun.MultiLineText
  android:id="@+id/textNotes"
  android:layout_height="wrap_content"
  android:minHeight="100dp"
  android:layout_width="wrap_content"
  android:hint="Notes"
  android:textSize="20sp"
  android:padding="7dp"
  android:maxLines="4"/> 
user3525689
quelle
5

Für die Aktion Fertig können Sie Folgendes verwenden:

XML

android:inputType="text|textCapSentences"    

JAVA

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

Ich hoffe, es funktioniert für Sie.

Alex Zaraos
quelle
1

Anscheinend lautet die Antwort auf die ursprüngliche Frage Ja, aber ich glaube, das Android-Team versucht, Entwickler dazu zu bringen, ein wenig darüber nachzudenken, wie sie den mehrzeiligen EditText verwenden. Sie möchten, dass die Eingabetaste Zeilenumbrüche hinzufügt, und erwarten wahrscheinlich, dass Sie eine Schaltfläche oder ein anderes Eingabemittel bereitstellen, um das Ereignis auszulösen, mit dem Sie fertig sind.

Ich habe das gleiche Problem und meine offensichtliche Lösung bestand darin, einfach eine Schaltfläche "Fertig" hinzuzufügen und die Eingabetaste die Zeilenumbrüche hinzufügen zu lassen.

Mullins
quelle
Entschuldigung, ich war mit meiner Frage möglicherweise nicht klar genug. Die mehreren Zeilen dienen zum Soft-Wrapping einer einzeiligen Eingabe. dh Zeilenumbrüche sind nicht zulässig.
Ohhorob
@ Mullins: Haben Sie der SoftInput-Tastatur Ihre eigene Schaltfläche "Fertig" hinzugefügt? Wie haben Sie das gemacht, während Sie die "Eingabetaste" beibehalten haben?
Alex.veprik
Nee. Ich habe eine Schaltfläche "Fertig" auf der Benutzeroberfläche getrennt von der Tastatur erstellt.
Mullins
1
Nun, vielleicht sollte das Android-Team seinen eigenen Rat befolgen und die Aktionsschaltfläche des mehrzeiligen TextEdit in der Messaging-App dazu bringen, Zeilenumbrüche zu erstellen, anstatt die Nachricht zu senden.
Timmmm
0

Verwenden Sie dieses Attribut in Ihrem XML.

android: inputType = "textImeMultiLine"

android: imeOptions = "actionDone"

Gaurav
quelle