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 Inhalte angezeigt werden sollen:

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

Feature

Wertbezogene Textfelder

Statusbasierte Textfelder

Vorteil basierend auf dem Bundesstaat

Zustandsverwaltung

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

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

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

Visuelle Transformation

Mit VisualTransformation wird die Darstellung des angezeigten Texts geändert. Normalerweise wird sowohl die Eingabe- als auch die Ausgabeformatierung in einem einzigen Schritt verarbeitet.

InputTransformation wird verwendet, um die Eingabe des Nutzers zu ändern, bevor sie im Status gespeichert 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 Roh- 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.

Mit lineLimits: TextFieldLineLimits wird die Mindest- und Höchstanzahl der Zeilen konfiguriert, die das Textfeld einnehmen kann.

  • Beseitigt Unklarheiten bei der Konfiguration von Zeilenlimits durch Bereitstellung eines lineLimits-Parameters vom Typ TextFieldLineLimits.

Sicheres Textfeld

–

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

  • Sie können die Sicherheit im Hintergrund optimieren und erhalten eine vordefinierte Benutzeroberfläche mit textObfuscationMode.

Auf dieser Seite wird beschrieben, wie Sie TextField implementieren, die Eingabe von TextField gestalten und andere TextField-Optionen wie Tastaturoptionen konfigurieren und Nutzereingaben visuell transformieren.

TextField-Implementierung auswählen

Es gibt zwei Implementierungsstufen für TextField:

  1. TextField ist die Material Design-Implementierung. Wir empfehlen diese Implementierung, da sie den Material Design-Richtlinien entspricht:
    • Der Standardstil ist gefüllt.
    • OutlinedTextField ist die umrissene Version des Stils.
  2. Mit BasicTextField können Nutzer Text über die Hardware- oder Softwaretastatur bearbeiten. Es werden jedoch keine Dekorationen wie Hinweise oder Platzhalter bereitgestellt.

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 violetten 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. Es folgt 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 gegenüber BasicTextField, wenn Ihr Design ein Material TextField oder OutlinedTextField erfordert. BasicTextField sollte jedoch verwendet werden, wenn Designs erstellt werden, die keine Dekorationen aus der Material-Spezifikation benötigen.

Stileingabe mit Brush API

Mit der Brush API können Sie TextField-Elemente noch besser gestalten. Im folgenden Abschnitt wird beschrieben, wie Sie mit einem Pinsel einen farbigen Verlauf in TextField-Eingaben einfügen.

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

Farbverläufe mit TextStyle implementieren

Wenn Sie beim Tippen in einem TextField einen Farbverlauf implementieren möchten, legen Sie den gewünschten Pinsel als TextStyle für das TextField fest. In diesem Beispiel verwenden wir einen integrierten Pinsel mit einem linearGradient, um den Regenbogenverlaufseffekt anzuzeigen, 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 wird in ein Textfeld eingegeben und mit einem Regenbogenfarbverlaufseffekt dargestellt.
Abbildung 1: Ein Regenbogenfarbverlauf-Effekt für TextField-Inhalte.

Status von Textfeldern verwalten

TextField verwendet für Inhalt und Auswahl eine spezielle Status-Holder-Klasse namens TextFieldState. TextFieldState ist so konzipiert, dass es überall in Ihrer Architektur platziert werden kann. TextFieldState bietet zwei Haupteigenschaften:

  • initialText: Inhalt des 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 TextFieldState den gesamten Eingabefluss vollständig kapselt. Dazu gehört die Verwendung der richtigen zugrunde liegenden Datenstrukturen, das Inlining von Filtern und Formatierungen sowie die Synchronisierung aller Änderungen aus verschiedenen Quellen.

Mit TextFieldState() können Sie den Status in TextField übertragen. Dazu empfehlen wir die Funktion rememberTextFieldState(). Mit rememberTextFieldState() wird die TextFieldState-Instanz in Ihrer Composable erstellt, dafür gesorgt, dass das Zustandsobjekt gespeichert wird, und eine integrierte Speicher- und Wiederherstellungsfunktion bereitgestellt:

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

rememberTextFieldState kann einen leeren Parameter oder einen anfänglichen Wert haben, der bei der Initialisierung den Wert des Texts darstellt. Wenn bei einer nachfolgenden Neukomposition 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 Ausgangstext.

Text mit TextFieldBuffer ändern

Ein TextFieldBuffer dient als bearbeitbarer Textcontainer, ähnlich wie ein StringBuilder. Sie 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 in TextFieldState übernommen oder im Fall von OutputTransformation an die Rendering-Pipeline weitergegeben.

Sie können den Inhalt des Puffers mit Standardbearbeitungsfunktionen wie append, insert, replace oder delete ändern. Wenn Sie den Auswahlstatus ändern möchten, legen Sie entweder direkt die Variable selection: TextRange fest oder verwenden Sie Hilfsfunktionen wie placeCursorAtEnd oder selectAll. Die Auswahl selbst wird durch ein TextRange dargestellt, wobei der Startindex inklusive und der Endindex exklusive ist. Ein TextRange mit identischen Start- und Endwerten, z. B. (3, 3), gibt eine Cursorposition an, bei 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 Ihre Statusvariable bearbeiten können:

  • edit: Hiermit können Sie den Statusinhalt bearbeiten und erhalten TextFieldBuffer-Funktionen, mit denen Sie Methoden wie insert, replace und append 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)

Informationen zu anderen TextFieldState-Funktionen finden Sie in der Referenz zu TextFieldState.

Benutzereingabe ä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 Ihre TextField beispielsweise eine amerikanische Telefonnummer akzeptiert, möchten Sie nur 10 Ziffern akzeptieren. Die Ergebnisse von InputTransformation werden in TextFieldState gespeichert.

Es gibt integrierte Filter für gängige InputTransformation-Anwendungsfälle. So begrenzen Sie die Länge: Rufen Sie InputTransformation.maxLength() auf:

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

Benutzerdefinierte Transformationen für Eingaben

InputTransformation ist eine Schnittstelle mit einer einzelnen Funktion. Bei der Implementierung Ihres benutzerdefinierten InputTransformation 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 Ziffern in TextField zulässt:

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

Eingabetransformationen verketten

Wenn Sie mehrere Filter auf Ihre Texteingabe anwenden möchten, verketten Sie InputTransformation-Elemente mit der Erweiterungsfunktion then. 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, akzeptiert die TextField-Eingabe maximal 10 Ziffern.

Eingabe vor der Anzeige formatieren

Mit OutputTransformation 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. Wenn Sie auf dem vorherigen Beispiel für Telefonnummern aufbauen, müssen Sie Klammern und Bindestriche an den entsprechenden Stellen hinzufügen:

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

Dies ist die aktualisierte Methode für die Verarbeitung von VisualTransformations in wertbasierten TextFields. Der Hauptunterschied besteht darin, dass Sie die Offsetzuordnungen nicht berechnen müssen.

OutputTransformation ist eine Schnittstelle mit einer einzigen abstrakten Methode. 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 an Index 0 eine öffnende Klammer, an Index 4 eine schließende Klammer und an Index 8 einen Bindestrich in OutputTransformation ein:

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, wie Texteingaben transformiert werden, bevor sie als Text ausgegeben 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 ein InputTransformation gefiltert, das im TextFieldState gespeichert wird.
  3. Die Eingabe wird zur Formatierung durch ein OutputTransformation geleitet.
  4. Die Eingabe wird in der TextField angezeigt.

Tastaturoptionen festlegen

Unter TextField können Sie Tastatureinstellungen 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 angegebenen Optionen entspricht. Hier finden Sie eine Liste der unterstützten Tastaturoptionen:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Zusätzliche Ressourcen