TextField
可讓使用者輸入及修改文字。本頁面說明如何實作 TextField
、設定 TextField
輸入內容的樣式,以及設定其他 TextField
選項,例如鍵盤選項和視覺轉換使用者輸入內容。
選擇 TextField
實作方式
TextField
實作分為兩個層級:
TextField
為質感設計實作。建議您選擇此實作程序,因為符合Material Design 設計準則:- 預設樣式為「填入」
OutlinedTextField
是外框樣式版本
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
或 OutlinedTextField
,建議使用 TextField
而非 BasicTextField
。然而,如果建構的設計不需要使用材質規格的裝飾,則應使用 BasicTextField
。
使用 Brush API 設定輸入樣式
您可以在 TextField
中使用 Brush API 使用更進階的樣式。以下章節將說明如何使用 Brush 將彩色漸層新增至 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 狀態