Textfelder konfigurieren

Mit TextField können Nutzer Text eingeben und ändern. Es gibt zwei Arten von Textfeldern: statusbasierte Textfelder und wertbasierte Textfelder. Wählen Sie den Typ aus, für den Inhalte angezeigt werden sollen:

Wir empfehlen die Verwendung von statusbasierten Textfeldern, da sie einen umfassenderen und zuverlässigeren Ansatz zur Verwaltung des Status eines TextField bieten. In der folgenden Tabelle werden die Unterschiede zwischen diesen Arten von Textfeldern beschrieben. Außerdem werden die wichtigsten Vorteile von statusbasierten Textfeldern aufgeführt:

Funktion

Wertbezogene Textfelder

Statusabhängige Textfelder

Länderspezifischer Vorteil

Zustandsverwaltung

Aktualisiert den Status des Textfelds mit dem onValueChange-Callback. Sie sind dafür verantwortlich, die value in Ihrem eigenen Bundesstaat anhand der von onValueChange gemeldeten Änderungen zu aktualisieren.

Verwendet explizit ein TextFieldState-Objekt, um den Status der Texteingabe (Wert, Auswahl, Zusammensetzung) zu verwalten. Dieser Status kann gespeichert und geteilt werden.

  • Der onValueChange-Callback wurde entfernt, sodass Sie kein asynchrones Verhalten mehr einführen können.
  • Der Status bleibt nach der Neuzusammensetzung, Konfiguration und Beendigung des Prozesses erhalten.

Visuelle Transformation

Mit VisualTransformation können Sie die Darstellung des angezeigten Texts ändern. Dabei werden in der Regel sowohl die Eingabe- als auch die Ausgabeformatierung in einem einzigen Schritt verarbeitet.

Mit InputTransformation wird die Eingabe des Nutzers geändert, bevor sie im Status gespeichert wird. Mit OutputTransformation wird der Inhalt des Textfelds formatiert, ohne die zugrunde liegenden Statusdaten zu ändern.

  • Sie müssen die Offsetzuordnung zwischen dem ursprünglichen Rohtext und dem transformierten Text mit OutputTransformation nicht mehr angeben.

Zeilenlimits

Mit singleLine: Boolean, maxLines: Int und minLines: Int lässt sich die Anzahl der Zeilen steuern.

Mit lineLimits: TextFieldLineLimits wird die minimale und maximale Anzahl von Zeilen konfiguriert, die das Textfeld umfassen kann.

  • Durch Angabe eines lineLimits-Parameters vom Typ TextFieldLineLimits werden Unklarheiten bei der Konfiguration von Zeilenlimits beseitigt.

Sicheres Textfeld

SecureTextField ist ein zusammensetzbares Element, das auf zustandsbasierten Textfeldern für das Schreiben eines Passwortfelds basiert.

  • Ermöglicht die Optimierung der Sicherheit im Hintergrund und bietet eine vordefinierte Benutzeroberfläche mit textObfuscationMode.

Auf dieser Seite wird beschrieben, wie Sie TextField implementieren, die TextField-Eingabe formatieren und andere TextField-Optionen konfigurieren, z. B. Tastaturoptionen und die visuelle Transformation von Nutzereingaben.

TextField-Implementierung auswählen

Es gibt zwei Ebenen der TextField-Implementierung:

  1. TextField ist die Material Design-Implementierung. Wir empfehlen diese Implementierung, da sie den Material Design-Richtlinien entspricht:
  2. Mit BasicTextField können Nutzer Text über eine Hardware- oder Softwaretastatur bearbeiten, es werden jedoch keine Verzierungen wie Hinweise oder Platzhalter angezeigt.

TextField(
    state = rememberTextFieldState(initialText = "Hello"),
    label = { Text("Label") }
)

Ein bearbeitbares Textfeld mit dem Wort

OutlinedTextField(
    state = rememberTextFieldState(),
    label = { Text("Label") }
)

Ein bearbeitbares Textfeld mit einem lilafarbenen Rahmen und Label.

Stil-TextField-

TextField und BasicTextField haben viele gemeinsame Parameter für die Anpassung. Eine vollständige Liste für TextField finden Sie im TextField-Quellcode. Im Folgenden finden Sie eine unvollständige Liste einiger nützlicher Parameter:

  • textStyle
  • lineLimits

TextField(
    state = rememberTextFieldState("Hello\nWorld\nInvisible"),
    lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2),
    placeholder = { Text("") },
    textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
    label = { Text("Enter text") },
    modifier = Modifier.padding(20.dp)
)

Ein mehrzeiliges Textfeld mit zwei bearbeitbaren Zeilen und dem Label

Wir empfehlen TextField anstelle von BasicTextField, wenn Ihr Design ein Material vom Typ TextField oder OutlinedTextField erfordert. BasicTextField sollte jedoch verwendet werden, wenn Designs erstellt werden, für die die Verzierungen aus der Material-Spezifikation nicht erforderlich sind.

Stil für Eingaben mit der Brush API festlegen

Mit der Brush API können Sie Ihr TextField noch weiter anpassen. Im folgenden Abschnitt wird beschrieben, wie Sie mit einem Pinsel einem TextField-Eingabeelement einen farbigen Farbverlauf hinzufügen.

Weitere Informationen zur Verwendung der Brush API zum Formatieren von Text finden Sie unter Erweitertes Styling mit der Brush API aktivieren.

Farbige Farbverläufe mit TextStyle implementieren

Wenn Sie beim Tippen in einem TextField einen Farbverlauf einfügen möchten, legen Sie den gewünschten Pinsel als TextStyle für das TextField fest. In diesem Beispiel verwenden wir einen integrierten Pinsel mit einer linearGradient, um den Regenbogen-Gradienteneffekt zu sehen, während Text in die TextField eingegeben wird.

val brush = remember {
    Brush.linearGradient(
        colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta)
    )
}
TextField(
    state = rememberTextFieldState(), textStyle = TextStyle(brush = brush)
)

Mit „buildAnnotatedString“, „SpanStyle“ und „linearGradient“ können Sie nur einen Teil des Texts anpassen.
Abbildung 1 Ein Regenbogen-Farbverlauf für TextField-Inhalte

Status des Textfelds verwalten

TextField verwendet eine spezielle Statushalterklasse namens TextFieldState für den Inhalt und die aktuelle Auswahl. TextFieldState kann überall dort angebracht werden, wo es in Ihre Architektur passt. TextFieldState bietet zwei Haupteigenschaften:

  • initialText: Inhalt des TextField.
  • initialSelection: Gibt an, wo sich der Cursor oder die Auswahl derzeit befindet.

Was TextFieldState von anderen Ansätzen wie dem onValueChange-Rückruf unterscheidet, ist, dass TextFieldState den gesamten Eingabefluss vollständig kapselt. Dazu gehört die Verwendung der richtigen Datenstrukturen, das Einfügen von Filtern und Formatierungselementen sowie die Synchronisierung aller Änderungen aus verschiedenen Quellen.

Mit TextFieldState() können Sie den Status in TextField hochladen. Wir empfehlen dazu die Funktion rememberTextFieldState(). rememberTextFieldState() erstellt die TextFieldState-Instanz in Ihrem Composeable, sorgt dafür, dass das Statusobjekt gespeichert wird, und bietet eine integrierte Funktion zum Speichern und Wiederherstellen:

val usernameState = rememberTextFieldState()
TextField(
    state = usernameState,
    lineLimits = TextFieldLineLimits.SingleLine,
    placeholder = { Text("Enter Username") }
)

rememberTextFieldState kann einen leeren Parameter oder einen angegebenen Anfangswert haben, der den Textwert bei der Initialisierung darstellt. Wenn bei einer nachfolgenden Neuzusammensetzung ein anderer Wert übergeben wird, wird der Wert des Status nicht aktualisiert. Wenn Sie den Status nach der Initialisierung aktualisieren möchten, rufen Sie die Bearbeitungsmethoden für TextFieldState auf.

TextField(
    state = rememberTextFieldState(initialText = "Username"),
    lineLimits = TextFieldLineLimits.SingleLine,
)

Ein Textfeld mit dem Text „Nutzername“, der im Textfeld angezeigt wird.
Abbildung 2: TextField mit „Nutzername“ als Anfangstext

Text mit TextFieldBuffer ändern

Ein TextFieldBuffer dient als bearbeitbarer Textcontainer, der in seiner Funktion einem StringBuilder ähnelt. Sie enthält sowohl den Textinhalt als auch Informationen zur aktuellen Auswahl.

TextFieldBuffer wird häufig als Empfängerbereich für Funktionen wie TextFieldState.edit, InputTransformation.transformInput oder OutputTransformation.transformOutput verwendet. In diesen Funktionen können Sie die TextFieldBuffer bei Bedarf lesen oder aktualisieren. Anschließend werden diese Änderungen entweder in TextFieldState übernommen oder im Fall von OutputTransformation an die Rendering-Pipeline übergeben.

Sie können Standardbearbeitungsfunktionen wie append, insert, replace oder delete verwenden, um den Inhalt des Buffers zu ändern. Wenn Sie den Auswahlstatus ändern möchten, können Sie entweder die Variable selection: TextRange direkt festlegen oder Dienstfunktionen wie placeCursorAtEnd oder selectAll verwenden. Die Auswahl selbst wird durch eine TextRange dargestellt, wobei der Startindex einschließend und der Endindex ausschließend ist. Ein TextRange mit identischen Anfangs- und Endwerten wie (3, 3) gibt die Cursorposition an, an der derzeit keine Zeichen ausgewählt sind.

val phoneNumberState = rememberTextFieldState()

LaunchedEffect(phoneNumberState) {
    phoneNumberState.edit { // TextFieldBuffer scope
        append("123456789")
    }
}

TextField(
    state = phoneNumberState,
    inputTransformation = InputTransformation { // TextFieldBuffer scope
        if (asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    },
    outputTransformation = OutputTransformation {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
)

Text in TextFieldState bearbeiten

Es gibt mehrere Methoden, mit denen Sie den Status direkt über die Statusvariable bearbeiten können:

  • edit: Hier können Sie den Statusinhalt bearbeiten und TextFieldBuffer-Funktionen verwenden, um Methoden wie insert, replace und append zu nutzen.

    val usernameState = rememberTextFieldState("I love Android")
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    usernameState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    usernameState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • setTextAndPlaceCursorAtEnd: Der aktuelle Text wird gelöscht, durch den angegebenen Text ersetzt und der Cursor wird ans Ende gesetzt.

    usernameState.setTextAndPlaceCursorAtEnd("I really love Android")
    // textFieldState.text : I really love Android
    // textFieldState.selection : TextRange(21, 21)

  • clearText: Löscht den gesamten Text.

    usernameState.clearText()
    // textFieldState.text :
    // textFieldState.selection : TextRange(0, 0)

Weitere TextFieldState-Funktionen finden Sie in der TextFieldState-Referenz.

Nutzereingabe ändern

In den folgenden Abschnitten wird beschrieben, wie Sie die Nutzereingabe ändern. Mit der Eingabetransformation können Sie TextField-Eingabe während der Eingabe des Nutzers filtern. Die Ausgabetransformation formatiert die Nutzereingabe, bevor sie auf dem Bildschirm angezeigt wird.

Nutzereingabe mit Eingabetransformationen filtern

Mit einer Eingabetransformation können Sie die Eingaben der Nutzer filtern. Wenn Sie beispielsweise eine US-amerikanische Telefonnummer in TextField eingeben möchten, sollten Sie nur 10 Ziffern zulassen. Die Ergebnisse der InputTransformation werden in der TextFieldState gespeichert.

Es gibt integrierte Filter für gängige InputTransformation-Anwendungsfälle. Wenn Sie die Länge einschränken möchten, rufen Sie InputTransformation.maxLength() auf:

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine,
    inputTransformation = InputTransformation.maxLength(10)
)

Benutzerdefinierte Eingabetransformationen

InputTransformation ist eine Schnittstelle mit einer einzelnen Funktion. Wenn Sie Ihre benutzerdefinierte InputTransformation implementieren, müssen Sie Folgendes überschreiben:TextFieldBuffer.transformInput

class CustomInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
    }
}

Fügen Sie für eine Telefonnummer eine benutzerdefinierte Eingabetransformation hinzu, die nur die Eingabe von Ziffern in das Feld TextField zulässt:

class DigitOnlyInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
        if (!TextUtils.isDigitsOnly(asCharSequence())) {
            revertAllChanges()
        }
    }
}

Eingabetransformationen verketten

Wenn Sie Ihrer Textzeile mehrere Filter hinzufügen möchten, können Sie InputTransformation-Elemente mithilfe der Erweiterungsfunktion then verknüpfen. Filter werden nacheinander ausgeführt. Es empfiehlt sich, zuerst die selektivsten Filter anzuwenden, um unnötige Transformationen von Daten zu vermeiden, die letztendlich herausgefiltert werden.

TextField(
    state = rememberTextFieldState(),
    inputTransformation = InputTransformation.maxLength(6)
        .then(CustomInputTransformation()),
)

Nachdem Sie Eingabetransformationen hinzugefügt haben, können für TextField maximal 10 Ziffern eingegeben werden.

Eingabe vor der Anzeige formatieren

Mit OutputTransformations können Sie die Nutzereingabe formatieren, bevor sie auf dem Bildschirm gerendert wird. Im Gegensatz zu InputTransformation wird die Formatierung, die über OutputTransformation erfolgt, nicht in TextFieldState gespeichert. Aufbauend auf dem vorherigen Beispiel für eine Telefonnummer müssen Sie an den entsprechenden Stellen Klammern und Bindestriche einfügen:

Eine US-amerikanische Telefonnummer, korrekt formatiert mit Klammern, Bindestriche und entsprechenden Indizes.
Abbildung 3: Eine US-amerikanische Telefonnummer mit korrekter Formatierung und entsprechenden Indizes.

Dies ist die aktualisierte Methode zur Verarbeitung von VisualTransformations in wertbasierten TextFields. Ein wichtiger Unterschied besteht darin, dass Sie die Offsetzuordnungen nicht berechnen müssen.

OutputTransformation ist eine einzelne abstrakte Methodenschnittstelle. Wenn Sie eine benutzerdefinierte OutputTransformation implementieren möchten, müssen Sie die Methode transformOutput überschreiben:

class CustomOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
    }
}

Wenn Sie eine Telefonnummer formatieren möchten, fügen Sie OutputTransformation eine öffnende Klammer an Index 0, eine schließende Klammer an Index 4 und einen Bindestrich an Index 8 hinzu:

class PhoneNumberOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
}

Fügen Sie als Nächstes OutputTransformation zu TextField hinzu:

TextField(
    state = rememberTextFieldState(),
    outputTransformation = PhoneNumberOutputTransformation()
)

Funktionsweise von Transformationen

Das folgende Diagramm zeigt den Ablauf von der Texteingabe über die Transformation bis zur Ausgabe:

Eine Visualisierung, wie Texteingaben transformiert werden, bevor sie zu Textausgaben werden.
Abbildung 4: Ein Diagramm, das zeigt, wie Texteingaben transformiert werden, bevor sie zu Textausgaben werden.
  1. Eingaben werden von der Eingabequelle empfangen.
  2. Die Eingabe wird durch einen InputTransformation gefiltert, der im TextFieldState gespeichert wird.
  3. Die Eingabe wird zur Formatierung an einen OutputTransformation übergeben.
  4. Die Eingabe wird in TextField angezeigt.

Tastaturoptionen festlegen

Über TextField können Sie Tastaturkonfigurationsoptionen wie das Tastaturlayout festlegen oder die Autokorrektur aktivieren, sofern sie von der Tastatur unterstützt wird. Einige Optionen sind möglicherweise nicht verfügbar, wenn die Softwaretastatur nicht den hier aufgeführten Optionen entspricht. Hier ist eine Liste der unterstützten Tastaturoptionen:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Zusätzliche Ressourcen