TextField
可讓使用者輸入及修改文字。本頁面說明如何實作 TextField
、設定 TextField
輸入樣式,並設定其他 TextField
選項,例如鍵盤選項以及以視覺化方式轉換使用者輸入內容。
選擇 TextField
實作方式
TextField
實作分為兩個層級:
TextField
為質感設計實作。建議您選擇此實作項目,因為它符合 Material Design 指南:BasicTextField
可讓使用者透過硬體或軟體鍵盤編輯文字,但不提供提示或預留位置等裝飾。
@Composable fun SimpleFilledTextFieldSample() { var text by remember { mutableStateOf("Hello") } TextField( value = text, onValueChange = { text = it }, label = { Text("Label") } ) }
@Composable fun SimpleOutlinedTextFieldSample() { var text by remember { mutableStateOf("") } OutlinedTextField( value = text, onValueChange = { text = it }, label = { Text("Label") } ) }
樣式 TextField
TextField
和 BasicTextField
會共用許多常用參數來自訂這些參數。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) ) }
如果設計需要 Material TextField
或 OutlineTextField
,建議使用 TextField
,而非 BasicTextField
。不過,如果建構的設計不需要使用 Material Design 規格的裝飾,則應使用 BasicTextField
。
使用 Brush API 設定樣式輸入
您可以在 TextField
中使用 Brush API 使用更進階的樣式。以下章節說明如何使用筆刷為 TextField
輸入內容新增彩色漸層。
如要進一步瞭解如何使用 Brush API 設定文字樣式,請參閱「使用 Brush API 啟用進階樣式」。
使用 TextStyle
實作彩色漸層
如要在 TextField
內輸入時實作彩色漸層,請將所選筆刷設為 TextField
的 TextStyle
。在此範例中,我們使用內建筆刷搭配 linearGradient
,在文字於 TextField
中輸入文字時,查看彩虹梯度效果。
var text by remember { mutableStateOf("") } val brush = remember { Brush.linearGradient( colors = rainbowColors ) } TextField( value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush) )
設定鍵盤選項
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' } } ) }
如要在清理文字時控制遊標位置,請將 TextField
的 TextFieldValue
超載做為狀態的一部分。
狀態的最佳做法
為了防止應用程式的輸入問題,以下一系列最佳做法說明如何定義及更新 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
的正確性。如果不是,您可以使用可組合項或狀態容器類別做為可靠資料來源。如要進一步瞭解提升狀態的位置,請參閱狀態提升說明文件。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 構建您的 Compose UI
- 狀態和 Jetpack Compose
- 在 Compose 中儲存 UI 狀態