Textfelder konfigurieren

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

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

Feature

Wertbasierte Textfelder

Statusbasierte Textfelder

Staatliche Leistungen

Zustandsverwaltung

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

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

  • Der Callback onValueChange wurde entfernt, sodass Sie keine asynchronen Verhaltensweisen mehr einführen können.
  • Der Status bleibt bei Neuzusammensetzung, Konfiguration und Prozessbeendigung erhalten.

Visuelle Transformation

Verwendet VisualTransformation, um die Darstellung des angezeigten Texts zu ändern. Dabei werden in der Regel sowohl die Eingabe- als auch die Ausgabeformatierung in einem einzigen Schritt verarbeitet.

Verwendet InputTransformation, um die Eingabe des Nutzers zu ändern, bevor sie in den Status übernommen wird, und OutputTransformation, um den Inhalt des Textfelds zu formatieren, ohne die zugrunde liegenden Statusdaten zu ändern.

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

Zeilenlimits

Akzeptiert singleLine: Boolean, maxLines: Int und minLines: Int, um die Anzahl der Zeilen zu steuern.

Verwendet lineLimits: TextFieldLineLimits, um die minimale und maximale Anzahl von Zeilen zu konfigurieren, die das Textfeld belegen kann.

  • Entfernt Mehrdeutigkeiten beim Konfigurieren von Zeilenlimits durch Bereitstellen eines lineLimits-Parameters vom Typ TextFieldLineLimits.

Sicheres Textfeld

–

SecureTextField ist eine zusammensetzbare Funktion, die auf zustandsbasierten Textfeldern aufbaut und zum Schreiben eines Passwortfelds verwendet wird.

  • 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 gestalten 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:
    • Der Standardstil ist filled.
    • OutlinedTextField ist die umrandete Stilversion.
  2. BasicTextField ermöglicht es Nutzern, Text über die Hardware- oder Softwaretastatur zu bearbeiten, bietet aber keine Dekorationen wie Hinweise oder Platzhalter.

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

Ein bearbeitbares Textfeld mit dem Wort

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

Ein bearbeitbares Textfeld mit violettem Rahmen und Label.

Stil TextField

TextField und BasicTextField haben viele gemeinsame Parameter für die Anpassung. Die vollständige Liste für TextField ist im TextField-Quellcode verfügbar. Dies ist 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 TextField mit zwei bearbeitbaren Zeilen und dem Label

Wir empfehlen TextField anstelle von BasicTextField, wenn Ihr Design ein TextField oder OutlinedTextField von Material erfordert. BasicTextField sollte jedoch verwendet werden, wenn Designs erstellt werden, die die Dekorationen aus der Material-Spezifikation nicht benötigen.

Stileingabe mit der Brush API

Für erweiterte Stile in TextField können Sie die Brush API verwenden. Im folgenden Abschnitt wird beschrieben, wie Sie mit einem Brush einen Farbverlauf zu einer TextField-Eingabe hinzufügen können.

Weitere Informationen zum Formatieren von Text mit der Brush API finden Sie unter Erweiterte Formatierung mit der Brush API aktivieren.

Farbverläufe mit TextStyle implementieren

Wenn Sie einen Farbverlauf implementieren möchten, während Sie in einem TextField-Element Text eingeben, legen Sie den gewünschten Pinsel als TextStyle für das TextField-Element fest. In diesem Beispiel verwenden wir einen integrierten Pinsel mit einem linearGradient, um den Regenbogenverlaufseffekt zu sehen, während Text in das 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)
)

Text, der in ein Textfeld eingegeben wird und einen Regenbogen-Farbverlaufseffekt zeigt.
Abbildung 1: Ein Regenbogenfarbverlauf für TextField-Inhalte.

Status des Textfelds verwalten

TextField verwendet für Inhalt und Auswahl eine dedizierte State-Holder-Klasse namens TextFieldState. TextFieldState ist so konzipiert, dass es überall in Ihrer Architektur eingesetzt werden kann. TextFieldState bietet zwei Hauptattribute:

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

TextFieldState unterscheidet sich von anderen Ansätzen wie dem onValueChange-Callback dadurch, dass TextFieldStateder gesamte Eingabefluss vollständig gekapselt wird. Dazu gehört die Verwendung der richtigen zugrunde liegenden Datenstrukturen, das Inlining von Filtern und Formatierern sowie die Synchronisierung aller Änderungen aus verschiedenen Quellen.

Mit TextFieldState() können Sie den Status in TextField hochziehen. Hierfür empfehlen wir die Funktion rememberTextFieldState(). rememberTextFieldState() erstellt die TextFieldState-Instanz in Ihrer zusammensetzbaren Funktion, sorgt dafür, dass das Zustandsobjekt gespeichert wird, und bietet integrierte Funktionen zum Speichern und Wiederherstellen:

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

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

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

Ein TextField mit dem Text „Nutzername“ im Textfeld.
Abbildung 2. TextField mit „Nutzername“ als Anfangstext.

Text mit TextFieldBuffer ändern

Ein TextFieldBuffer dient als bearbeitbarer Textcontainer, ähnlich wie ein StringBuilder. Es enthält sowohl den Textinhalt als auch Informationen zur 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 nach Bedarf lesen oder aktualisieren. Anschließend werden diese Änderungen entweder an TextFieldState übergeben oder im Fall von OutputTransformation an die Rendering-Pipeline weitergegeben.

Sie können Standardbearbeitungsfunktionen wie append, insert, replace oder delete verwenden, um den Inhalt des Puffers zu ändern. Wenn Sie den Auswahlstatus ändern möchten, legen Sie entweder die Variable selection: TextRange direkt fest oder verwenden Sie Dienstfunktionen wie placeCursorAtEnd oder selectAll. Die Auswahl selbst wird durch ein TextRange dargestellt, wobei der Startindex inklusiv und der Endindex exklusiv ist. Ein TextRange mit identischen Start- und Endwerten, z. B. (3, 3), gibt eine Cursorposition an, an der keine Zeichen ausgewählt sind.

val phoneNumberState = rememberTextFieldState("1234567890")

TextField(
    state = phoneNumberState,
    keyboardOptions = KeyboardOptions(
        keyboardType = KeyboardType.Phone
    ),
    inputTransformation = InputTransformation.maxLength(10).then {
        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: Ermöglicht das Bearbeiten des Statusinhalts und bietet TextFieldBuffer-Funktionen, sodass Sie Methoden wie insert, replace, append und mehr verwenden können.

    // Initial textFieldState text passed in is "I love Android"
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    textFieldState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    textFieldState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • setTextAndPlaceCursorAtEnd: Löscht den aktuellen Text, ersetzt ihn durch den angegebenen Text und setzt den Cursor ans Ende.

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

  • clearText: Löscht den gesamten Text.

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

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

Nutzereingabe ändern

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

Nutzereingaben mit Eingabetransformationen filtern

Mit einer Eingabetransformation können Sie Eingaben des Nutzers filtern. Wenn Ihr TextField beispielsweise eine US-amerikanische Telefonnummer akzeptiert, sollten Sie nur 10 Ziffern zulassen. Die Ergebnisse von InputTransformation werden in TextFieldState gespeichert.

Es gibt integrierte Filter für gängige InputTransformation-Anwendungsfälle. Wenn Sie die Länge begrenzen 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 einzigen Funktion. Wenn Sie Ihre benutzerdefinierte InputTransformation implementieren, müssen Sie TextFieldBuffer.transformInput überschreiben:

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 TextField zulässt:

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

Eingabetransformationen verketten

Wenn Sie Ihrer Texteingabe mehrere Filter hinzufügen möchten, verketten Sie InputTransformations mit der Erweiterungsfunktion then. Filter werden nacheinander ausgeführt. Als Best Practice sollten Sie zuerst die selektivsten Filter anwenden, um unnötige Transformationen von Daten zu vermeiden, die letztendlich herausgefiltert werden.

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

Nach dem Hinzufügen von Eingabetransformationen akzeptiert die Eingabe TextField maximal 10 Ziffern.

Eingabe vor der Anzeige formatieren

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

Eine US-amerikanische Telefonnummer, die korrekt mit Klammern, Bindestrichen und entsprechenden Indizes formatiert ist.
Abbildung 3: Eine US-amerikanische Telefonnummer mit korrekter Formatierung und entsprechenden Indexen.

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

OutputTransformation ist eine Schnittstelle mit einer einzelnen abstrakten Methode. Wenn Sie einen benutzerdefinierten 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 Ihrem OutputTransformation eine öffnende Klammer bei Index 0, eine schließende Klammer bei Index 4 und einen Bindestrich bei 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 Ihre OutputTransformation zu TextField hinzu:

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

Zusammenwirken von Transformationen

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

Eine Visualisierung, die zeigt, 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. Die Eingabe wird 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 der TextField dargestellt.

Tastaturoptionen festlegen

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

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Zusätzliche Ressourcen