Textfelder konfigurieren

Mit TextField können Nutzer Text eingeben und bearbeiten. 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 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 statusbasierten Textfeldern aufgeführt:

Funktion

Wertbezogene Textfelder

Statusbasierte Textfelder

Leistung auf Bundesstaatsebene

Zustandsverwaltung

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

Verwendet explizit ein TextFieldState-Objekt, um den Status 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 Status bleibt bei der Neuzusammensetzung, Konfiguration und beim Beenden des Prozesses 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.

Verwendet InputTransformation zum Ändern der Eingabe des Nutzers, bevor sie im Status gespeichert wird, und OutputTransformation zum Formatieren von Textfeldinhalten, ohne die zugrunde liegenden Statusdaten zu ändern.

  • Sie müssen die Offsetzuordnung 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 minimale und maximale Anzahl von 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.

  • 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 wie Tastaturoptionen konfigurieren und die Nutzereingabe visuell transformieren.

TextField-Implementierung auswählen

Es gibt zwei Implementierungsebenen für TextField:

  1. TextField ist die Material Design-Implementierung. Wir empfehlen Ihnen, diese Implementierung zu wählen, da sie den Material Design-Richtlinien entspricht:
    • Der Standardstil ist filled.
    • 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 lila 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. Hier 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 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.

Zeilenlimits konfigurieren

TextField-Composables unterstützen das Scrollen entlang einer einzelnen Achse. Das Scrollverhalten wird durch den Parameter lineLimits bestimmt. TextFields sind für das horizontale Scrollen in einer Zeile konfiguriert, während mehrzeilige TextFields vertikal scrollen.

Verwenden Sie TextFieldLineLimits, um die passende Zeilenkonfiguration für Ihre TextField auszuwählen:

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine
)

Einzeiliges Textfeld mit dem Text

Die SingleLine-Konfiguration hat die folgenden Merkmale:

  • Der Text wird nie umgebrochen und es sind keine neuen Zeilen zulässig.
  • TextField hat immer eine feste Höhe.
  • Wenn der Text überläuft, wird er horizontal gescrollt.

TextField(
    state = rememberTextFieldState("Hello\nWorld\nHello\nWorld"),
    lineLimits = TextFieldLineLimits.MultiLine(1, 4)
)

Ein mehrzeiliges Textfeld mit dem Text

Die MultiLine-Konfiguration hat die folgenden Merkmale:

  • Akzeptiert zwei Parameter: minHeightInLines und maxHeightInLines.
  • Das Textfeld ist mindestens minHeightInLines hoch.
  • Wenn der Text überläuft, wird er umgebrochen.
  • Wenn für den Text mehr Zeilen erforderlich sind, wird das Feld so lange vergrößert, bis es maxHeightInLines hoch ist. Dann wird vertikal gescrollt.

Stileingabe mit der Brush API

Mit der Brush API können Sie TextField noch komplexer gestalten. Im folgenden Abschnitt wird beschrieben, wie Sie mit einem Pinsel einen farbigen Verlauf in TextField-Eingaben einfü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 beim Tippen in einem TextField einen farbigen Verlauf 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 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 wird in ein Textfeld eingegeben und mit einem Regenbogenfarbverlaufseffekt dargestellt.
Abbildung 1: Ein Regenbogen-Farbverlaufseffekt für TextField-Inhalte.

Status von Textfeldern verwalten

TextField verwendet für Inhalt und Auswahl eine spezielle Statusinhaberklasse namens TextFieldState. TextFieldState kann überall in Ihrer Architektur platziert werden. 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 hochstufen. Wir empfehlen, dazu die Funktion rememberTextFieldState() zu verwenden. Mit rememberTextFieldState() wird die TextFieldState-Instanz in Ihrem 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 übergebenen Anfangswert haben, um den Wert des Texts bei der Initialisierung darzustellen. Wenn bei einer nachfolgenden Neuzusammenstellung ein anderer Wert übergeben wird, wird der Wert des Status 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 „Username“ (Nutzername) im Textfeld.
Abbildung 2: TextField mit „Nutzername“ als Ausgangstext.

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 in TextFieldState übernommen 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 Hilfsfunktionen wie placeCursorAtEnd oder selectAll. Die Auswahl selbst wird durch ein TextRange dargestellt, wobei der Startindex einbezogen und der Endindex ausgeschlossen wird. Ein TextRange mit identischen Start- und Endwerten, z. B. (3, 3), gibt eine Cursorposition ohne ausgewählte Zeichen an.

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: Ermöglicht es Ihnen, den Statusinhalt zu bearbeiten, und bietet Ihnen TextFieldBuffer-Funktionen, damit 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 an das 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 TextFieldState-Referenz.

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, möchten Sie nur 10 Ziffern zulassen. Die Ergebnisse von InputTransformation werden in TextFieldState gespeichert.

Es gibt integrierte Filter für häufige InputTransformation-Anwendungsfälle. Rufen Sie InputTransformation.maxLength() auf, um die Länge zu begrenzen:

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

Benutzerdefinierte Transformationen von Eingaben

InputTransformation ist eine Schnittstelle mit einer einzelnen 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 Ziffern in TextField zulässt:

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

Transformationen von Ketten-Eingaben

Wenn Sie Ihrer Texteingabe mehrere Filter hinzufügen möchten, können Sie InputTransformations mit der Erweiterungsfunktion then verketten. Filter werden nacheinander ausgeführt. Es empfiehlt sich, die selektivsten Filter zuerst 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 Sie für die TextField-Eingabe maximal 10 Ziffern verwenden.

Eingabe formatieren, bevor sie angezeigt wird

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 an den entsprechenden Stellen Klammern und Bindestriche 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 zum Verarbeiten von VisualTransformation in wertbasierten TextFields. Der Hauptunterschied besteht darin, dass Sie die Offsetzuordnungen nicht berechnen müssen.

OutputTransformation ist eine Schnittstelle mit einer einzelnen abstrakten Methode. Um eine benutzerdefinierte OutputTransformation zu implementieren, 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 an Index 0 eine öffnende und an Index 4 eine schließende Klammer sowie an Index 8 einen Bindestrich 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()
)

Zusammenwirken von Transformationen

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

Eine Visualisierung, wie Texteingaben Transformationen durchlaufen, bevor sie zu Textausgaben werden.
Abbildung 4. Ein Diagramm, das zeigt, wie Texteingaben Transformationen durchlaufen, bevor sie zu Textausgaben werden.
  1. 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 OutputTransformation geleitet.
  4. Die Eingabe wird in der TextField angezeigt.

Tastaturoptionen festlegen

Unter TextField können Sie Tastaturkonfigurationen 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

Die Klasse KeyboardOptions enthält jetzt einen neuen booleschen Parameter, showKeyboardOnFocus, den Sie speziell für TextField-Komponenten verwenden, die in TextFieldState eingebunden sind. Diese Option bestimmt das Verhalten der Softwaretastatur, wenn das TextField auf andere Weise als durch direkte Nutzerinteraktion (z. B. programmatisch) den Fokus erhält.

Wenn KeyboardOptions.showKeyboardOnFocus auf „true“ gesetzt ist, wird die Bildschirmtastatur nicht automatisch angezeigt, wenn TextField indirekt den Fokus erhält. In solchen Fällen muss der Nutzer explizit auf das TextField tippen, um die Tastatur aufzurufen.

Logik für Tastaturinteraktion definieren

Mit der Aktionsschaltfläche auf der Softwaretastatur von Android können Sie interaktive Antworten in Ihrer Anwendung erstellen. Weitere Informationen zum Konfigurieren der Aktionsschaltfläche finden Sie im Abschnitt Tastaturoptionen festlegen.

Eine Aktionsschaltfläche der Softwaretastatur (ein Häkchensymbol), die rot umrandet ist.
Abbildung 5. Aktionsschaltfläche auf der Bildschirmtastatur.

Mit dem Parameter onKeyboardAction können Sie festlegen, was passiert, wenn ein Nutzer auf diese Aktionsschaltfläche tippt. Dieser Parameter akzeptiert ein optionales funktionales Interface mit dem Namen KeyboardActionHandler. Die KeyboardActionHandler-Schnittstelle enthält eine einzelne Methode: onKeyboardAction(performDefaultAction: () -> Unit). Wenn Sie eine Implementierung für diese onKeyboardAction-Methode bereitstellen, können Sie benutzerdefinierte Logik einführen, die ausgeführt wird, wenn ein Nutzer die Aktionsschaltfläche der Tastatur drückt.

Für mehrere Standardtastaturaktionstypen sind standardmäßige Standardverhalten integriert. Wenn Sie beispielsweise ImeAction.Next oder ImeAction.Previous als Aktionstyp auswählen, wird der Fokus standardmäßig auf das nächste bzw. vorherige Eingabefeld verschoben. Ebenso wird die Softwaretastatur in der Regel geschlossen, wenn eine Aktionsschaltfläche auf ImeAction.Done eingestellt ist. Diese Standardfunktionen werden automatisch ausgeführt und erfordern keine KeyboardActionHandler.

Zusätzlich zu diesen Standardaktionen können Sie auch benutzerdefiniertes Verhalten implementieren. Wenn Sie KeyboardActionHandler bereitstellen, empfängt die onKeyboardAction-Methode eine performDefaultAction-Funktion. Sie können diese performDefaultAction()-Funktion an beliebiger Stelle in Ihrer benutzerdefinierten Logik aufrufen, um auch das standardmäßige Standardverhalten auszulösen, das mit der aktuellen IME-Aktion verknüpft ist.

TextField(
    state = textFieldViewModel.usernameState,
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
    onKeyboardAction = { performDefaultAction ->
        textFieldViewModel.validateUsername()
        performDefaultAction()
    }
)

In diesem Snippet wird ein häufiger Anwendungsfall auf einem Registrierungsbildschirm mit einem Feld für den Nutzernamen veranschaulicht. Für dieses Feld ist ImeAction.Next für die Tastatur-Schaltfläche ausgewählt. Diese Auswahl ermöglicht eine schnelle, nahtlose Navigation zum nachfolgenden Passwortfeld.

Zusätzlich zu dieser Standardnavigation muss ein Hintergrundvalidierungsprozess für den Nutzernamen gestartet werden, während der Nutzer sein Passwort eingibt. Damit das standardmäßige Fokuswechselverhalten von ImeAction.Next zusammen mit dieser benutzerdefinierten Validierungslogik beibehalten wird, wird die Funktion performDefaultAction() aufgerufen. Durch den Aufruf von performDefaultAction() wird implizit das zugrunde liegende Fokusverwaltungssystem ausgelöst, um den Fokus auf das nächste geeignete UI-Element zu verschieben. So wird der erwartete Navigationsfluss beibehalten.

Sicheres Passwortfeld erstellen

SecureTextField ist eine zusammensetzbare Funktion, die auf zustandsbasierten Textfeldern basiert und zum Schreiben eines Passwortfelds verwendet wird. Wir empfehlen, SecureTextField zum Erstellen von Passworttextfeldern zu verwenden, da die Zeicheneingabe standardmäßig ausgeblendet und die Aktionen „Ausschneiden“ und „Kopieren“ deaktiviert werden.

SecureTextField hat ein textObfuscationMode, das steuert, wie die Nutzereingabe von Zeichen angezeigt wird. textObfuscationMode bietet die folgenden Optionen:

  • Hidden: Blendet alle Eingaben aus. Standardverhalten auf Desktop-Plattformen

    Ein sicheres Textfeld, in dem eingegebene Zeichen verborgen werden.

  • Visible: Zeigt alle Eingaben an.

    Ein sicheres Textfeld, in dem eingegebene Zeichen sichtbar sind.

  • RevealLastTyped: Blendet alle Eingaben mit Ausnahme des letzten Zeichens aus. Standardverhalten auf Mobilgeräten.

    Ein sicheres Textfeld, in dem nur das zuletzt eingegebene Zeichen kurz angezeigt wird.

Zusätzliche Ressourcen