處理使用者輸入內容

TextField 可讓使用者輸入及修改文字。本頁面說明如何實作 TextField、設定 TextField 輸入內容的樣式,以及設定其他 TextField 選項,例如鍵盤選項和視覺轉換使用者輸入內容。

選擇 TextField 實作

TextField 實作分為兩個層級:

  1. TextField 為質感設計實作。建議您選擇此實作程序,因為符合Material Design 設計準則
    • 預設樣式為「填入」
    • OutlinedTextFieldoutline 樣式版本
  2. BasicTextField 可讓使用者透過硬體或軟體編輯文字 但未提供提示或預留位置等裝飾

@Composable
fun SimpleFilledTextFieldSample() {
    var text by remember { mutableStateOf("Hello") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

含有「Hello」字詞的可編輯文字欄位。

@Composable
fun SimpleOutlinedTextFieldSample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

可編輯的文字欄位,帶有紫色邊框和標籤。

樣式 TextField

TextFieldBasicTextField 共用許多常用參數,可供自訂 具體做法是指示 Kubernetes 建立並維護 一或多個代表這些 Pod 的物件TextField 原始碼內提供 TextField 的完整清單。以下列舉部分有用參數的內容:

  • singleLine
  • maxLines
  • textStyle

@Composable
fun StyledTextField() {
    var value by remember { mutableStateOf("Hello\nWorld\nInvisible") }

    TextField(
        value = value,
        onValueChange = { value = it },
        label = { Text("Enter text") },
        maxLines = 2,
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(20.dp)
    )
}

多行 TextField,含有兩行可編輯行加上標籤

如果設計需要 Material TextFieldOutlinedTextField,建議使用 TextField 而非 BasicTextField。然而,如果建構的設計不需要使用材質規格的裝飾,則應使用 BasicTextField

使用 Brush API 設定樣式輸入

您可以在 TextField 中使用 Brush API 使用更進階的樣式。 下一節說明如何使用筆刷新增彩色漸層 「TextField」輸入內容。

如要進一步瞭解如何使用 Brush API 設定文字樣式,請參閱「使用 Brush API 啟用進階樣式」。

使用 TextStyle 實作彩色漸層

如要在 TextField 中輸入時實作彩色漸層,請設定筆刷 做為 TextFieldTextStyle。本例使用 內建 linearGradient 的筆刷,可檢視彩虹梯度效果,如 文字會輸入至 TextField

var text by remember { mutableStateOf("") }
val brush = remember {
    Brush.linearGradient(
        colors = rainbowColors
    )
}
TextField(
    value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush)
)

使用 buildAnnotatedString 和 SpanStyle 搭配 linearGradient,只自訂某段文字。
圖 3.使用 buildAnnotatedStringSpanStyle 搭配 linearGradient,只自訂某段文字。

設定鍵盤選項

TextField 可讓您設定鍵盤設定選項 (例如鍵盤配置);或是啟用自動更正功能 (如果鍵盤有支援)。只有部分通知 如果螢幕鍵盤不符合 這裡提供的選項以下是支援的鍵盤選項清單:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

格式化輸入內容

TextField 可讓您設定 VisualTransformation 例如將字元替換成 * 做為密碼,或是 為信用卡號碼插入每 4 碼連字號:

@Composable
fun PasswordTextField() {
    var password by rememberSaveable { mutableStateOf("") }

    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Enter password") },
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
    )
}

密碼文字輸入欄位,文字遮蓋

您可以在 VisualTransformationSamples 原始碼中找到更多範例。

清理輸入內容

編輯文字的常見工作是移除前置字元,或在每次變更文字時轉換輸入字串。

做為模型,您應該假設每個 onValueChange 都可進行任意和大規模編輯。舉例來說,如果使用者使用自動更正功能,並以表情符號取代字詞或其他智慧編輯功能,就可能發生這種情況。目的地: 正確處理此情況並編寫任何轉換邏輯,假設 傳遞至 onValueChange 的目前文字與上一個或下一個文字無關 值,以便傳遞至 onValueChange

如要實作不允許內容開頭為零的文字欄位,可以在每次值變更時移除所有開頭的零。

@Composable
fun NoLeadingZeroes() {
    var input by rememberSaveable { mutableStateOf("") }
    TextField(
        value = input,
        onValueChange = { newText ->
            input = newText.trimStart { it == '0' }
        }
    )
}

如要在清除文字時控制游標位置,請使用 TextFieldTextFieldValue 超載做為狀態的一部分。

狀態的最佳做法

以下列出一系列最佳做法,說明如何定義及更新 TextField 狀態,以避免應用程式發生輸入問題。

  • 使用 MutableState 代表 TextField 狀態:請避免使用 StateFlow 等回應式串流來代表 TextField 狀態,因為這些結構可能會引入非同步延遲。

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • 避免延遲更新狀態:呼叫 onValueChange 時, TextField 會同步且立即:

// SignUpViewModel.kt

class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {

    var username by mutableStateOf("")
        private set

    fun updateUsername(input: String) {
        username = input
    }
}

// SignUpScreen.kt

@Composable
fun SignUpScreen(/*...*/) {

    OutlinedTextField(
        value = viewModel.username,
        onValueChange = { username -> viewModel.updateUsername(username) }
        /*...*/
    )
}

  • 定義狀態的位置:如果 TextField 狀態需要在您輸入時進行商業邏輯驗證,將狀態提升至 ViewModel 是正確的做法。如果不是,您可以使用可組合函式或狀態容器類別 並產生可靠結果如要進一步瞭解提升狀態的位置,請參閱狀態提升說明文件。

目前沒有任何建議。

建議 Google 帳戶。