TextField
可讓使用者輸入及修改文字。您可以使用兩種類型的文字欄位:狀態導向文字欄位和值導向文字欄位。選取要顯示內容的類型:
建議您使用狀態文字欄位,因為這類欄位可提供更完整且可靠的方式來管理 TextField
的狀態。下表列出這些類型文字欄位的差異,並說明以狀態為準的文字欄位提供的主要優勢:
功能 |
以價值為準文字欄位 |
狀態文字欄位 |
州福利 |
---|---|---|---|
狀態管理 |
使用 |
明確使用 |
|
視覺轉換 |
使用 |
使用 |
|
線條限制 |
接受 |
使用 |
|
安全文字欄位 |
無 |
|
|
本頁面說明如何實作 TextField
、樣式 TextField
輸入內容,以及設定其他 TextField
選項,例如鍵盤選項和視覺轉換使用者輸入內容。
選擇 TextField
實作
TextField
實作分為兩個層級:
TextField
為 Material Design 實作。建議您選擇此實作程序,因為符合Material Design 設計準則:- 預設樣式為「填入」
OutlinedTextField
是外框樣式版本
BasicTextField
可讓使用者透過硬體或軟體鍵盤編輯文字,但無法提供提示或預留位置等裝飾。
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
OutlinedTextField( state = rememberTextFieldState(), label = { Text("Label") } )
樣式 TextField
TextField
和 BasicTextField
共用許多常見的參數,可用於自訂。TextField
原始碼內提供 TextField
的完整清單。以下列舉部分有用參數的內容:
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) )
如果設計需要 Material TextField
或 OutlinedTextField
,建議使用 TextField
而非 BasicTextField
。然而,如果建構的設計不需要使用材質規格的裝飾,則應使用 BasicTextField
。
使用 Brush API 設定輸入樣式
您可以使用 Brush API 在 TextField
中套用更進階的樣式。以下章節將說明如何使用筆刷將彩色漸層新增至 TextField
輸入內容。
如要進一步瞭解如何使用 Brush API 設定文字樣式,請參閱「使用 Brush API 啟用進階樣式」。
使用 TextStyle
實作彩色漸層
如要在 TextField
中輸入文字時導入彩色漸層,請將所選的筆刷設為 TextField
的 TextStyle
。在本範例中,我們使用內建的筆刷搭配 linearGradient
,在 TextField
中輸入文字時,查看彩虹漸層效果。
val brush = remember { Brush.linearGradient( colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta) ) } TextField( state = rememberTextFieldState(), textStyle = TextStyle(brush = brush) )

TextField
內容的彩虹漸層效果。管理文字欄位狀態
TextField
會使用名為 TextFieldState
的專屬狀態容器類別,用於其內容和目前的選取項目。TextFieldState
的設計目的是在架構中適當的位置提升。TextFieldState
提供 2 個主要屬性:
initialText
:TextField
的內容。initialSelection
:指出游標或選取項目目前的位置。
TextFieldState
與其他方法 (例如 onValueChange
回呼) 的不同之處在於,TextFieldState
可完全封裝整個輸入流程。這包括使用正確的備援資料結構、內嵌篩選器和格式化工具,以及同步處理來自不同來源的所有編輯內容。
您可以使用 TextFieldState()
在 TextField
中提升狀態。為此,我們建議您使用 rememberTextFieldState()
函式。rememberTextFieldState()
會在可組合項中建立 TextFieldState
例項,確保狀態物件已記住,並提供內建的儲存和還原功能:
val usernameState = rememberTextFieldState() TextField( state = usernameState, lineLimits = TextFieldLineLimits.SingleLine, placeholder = { Text("Enter Username") } )
rememberTextFieldState
可以有空白參數,或傳入初始值,以便在初始化時代表文字的值。如果在後續重組中傳遞不同的值,狀態值就不會更新。如要在狀態初始化後更新狀態,請對 TextFieldState
呼叫編輯方法。
TextField( state = rememberTextFieldState(initialText = "Username"), lineLimits = TextFieldLineLimits.SingleLine, )

TextField
,其中「Username」為初始文字。使用 TextFieldBuffer
修改文字
TextFieldBuffer
是可編輯的文字容器,功能類似 StringBuilder
。它會同時保留文字內容和目前選取項目的相關資訊。
您經常會在 TextFieldState.edit
、InputTransformation.transformInput
或 OutputTransformation.transformOutput
等函式中,看到 TextFieldBuffer
做為接收器範圍。在這些函式中,您可以視需要讀取或更新 TextFieldBuffer
。之後,這些變更會提交至 TextFieldState
,或是在 OutputTransformation
的情況下傳遞至轉譯管道。
您可以使用標準編輯函式 (例如 append
、insert
、replace
或 delete
) 修改緩衝區的內容。如要變更選取狀態,請直接設定其 selection: TextRange
變數,或使用 placeCursorAtEnd
或 selectAll
等公用函式。選取項目本身由 TextRange
表示,其中起始索引包含起始值,結束索引則不包含結束值。TextRange
的起始和結束值相同 (例如 (3, 3)
),表示游標位置目前沒有選取任何字元。
val phoneNumberState = rememberTextFieldState() LaunchedEffect(phoneNumberState) { phoneNumberState.edit { // TextFieldBuffer scope append("123456789") } } TextField( state = phoneNumberState, inputTransformation = InputTransformation { // TextFieldBuffer scope if (asCharSequence().isDigitsOnly()) { revertAllChanges() } }, outputTransformation = OutputTransformation { if (length > 0) insert(0, "(") if (length > 4) insert(4, ")") if (length > 8) insert(8, "-") } )
在 TextFieldState
中編輯文字
您可以透過多種方法,直接透過狀態變數編輯狀態:
edit
:可讓您編輯狀態內容,並提供TextFieldBuffer
函式,讓您使用insert
、replace
、append
等方法。val usernameState = rememberTextFieldState("I love Android") // textFieldState.text : I love Android // textFieldState.selection: TextRange(14, 14) usernameState.edit { insert(14, "!") } // textFieldState.text : I love Android! // textFieldState.selection: TextRange(15, 15) usernameState.edit { replace(7, 14, "Compose") } // textFieldState.text : I love Compose! // textFieldState.selection: TextRange(15, 15) usernameState.edit { append("!!!") } // textFieldState.text : I love Compose!!!! // textFieldState.selection: TextRange(18, 18) usernameState.edit { selectAll() } // textFieldState.text : I love Compose!!!! // textFieldState.selection: TextRange(0, 18)
setTextAndPlaceCursorAtEnd
:清除目前的文字,並以指定的文字取代,然後將游標設為結尾。usernameState.setTextAndPlaceCursorAtEnd("I really love Android") // textFieldState.text : I really love Android // textFieldState.selection : TextRange(21, 21)
clearText
:清除所有文字。usernameState.clearText() // textFieldState.text : // textFieldState.selection : TextRange(0, 0)
如需其他 TextFieldState
函式,請參閱 TextFieldState
參考資料。
修改使用者輸入內容
以下各節說明如何修改使用者輸入內容。輸入轉換可讓您在使用者輸入內容時,篩選 TextField
輸入內容,而輸出轉換則會在使用者輸入內容顯示在畫面上之前,先對其格式化。
使用輸入轉換功能篩選使用者輸入內容
您可以使用輸入轉換功能篩選使用者輸入的內容。舉例來說,如果 TextField
會輸入美國電話號碼,您只想接受 10 位數字。InputTransformation
的結果會儲存在 TextFieldState
中。
內建篩選器可用於常見的 InputTransformation
用途。如要限制長度,請呼叫 InputTransformation.maxLength()
:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine, inputTransformation = InputTransformation.maxLength(10) )
自訂輸入轉換
InputTransformation
是單一函式介面。實作自訂 InputTransformation
時,您需要覆寫 TextFieldBuffer.transformInput
:
class CustomInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { } }
針對電話號碼,請新增自訂輸入轉換,只允許在 TextField
中輸入數字:
class DigitOnlyInputTransformation : InputTransformation { override fun TextFieldBuffer.transformInput() { if (!TextUtils.isDigitsOnly(asCharSequence())) { revertAllChanges() } } }
連結輸入轉換
如要在文字輸入內容上新增多個篩選器,請使用 then
擴充功能函式連結 InputTransformation
。系統會依序執行篩選器。最佳做法是先套用最具選擇性的篩選器,避免對最終會遭到篩除的資料進行不必要的轉換。
TextField( state = rememberTextFieldState(), inputTransformation = InputTransformation.maxLength(6) .then(CustomInputTransformation()), )
新增輸入轉換後,TextField
輸入內容最多可接受 10 位數。
在輸入內容顯示前先格式化
OutputTransformation
可讓您在使用者輸入內容顯示在螢幕上之前,先對其格式化。與 InputTransformation
不同,透過 OutputTransformation
完成的格式設定不會儲存在 TextFieldState
中。以先前的電話號碼範例為例,您需要在適當的位置加入括號和破折號:

這是在以值為基礎的 TextField
中處理 VisualTransformation
的更新方式,主要差異在於您不必計算其偏移對應項目。
OutputTransformation
是單一抽象方法介面。如要實作自訂 OutputTransformation
,您必須覆寫 transformOutput
方法:
class CustomOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { } }
如要設定電話號碼格式,請在 OutputTransformation
的索引 0 處新增開方括號,在索引 4 處新增結束方括號,並在索引 8 處新增破折號:
class PhoneNumberOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { if (length > 0) insert(0, "(") if (length > 4) insert(4, ")") if (length > 8) insert(8, "-") } }
接著,將 OutputTransformation
新增至 TextField
:
TextField( state = rememberTextFieldState(), outputTransformation = PhoneNumberOutputTransformation() )
轉換作業的搭配運作方式
下圖顯示從文字輸入到轉換至輸出內容的流程:

- 從輸入來源接收輸入內容。
- 輸入內容會透過
InputTransformation
進行篩選,並儲存在 TextFieldState 中。 - 輸入內容會傳遞至
OutputTransformation
進行格式設定。 - 輸入內容會顯示在
TextField
中。
設定鍵盤選項
TextField
可讓您設定鍵盤設定選項 (例如鍵盤配置);或是啟用自動更正功能 (如果鍵盤有支援)。如果螢幕鍵盤不符合此處提供的選項,則可能無法保證某些選項可以使用。以下是支援的鍵盤選項清單:
capitalization
autoCorrect
keyboardType
imeAction
其他資源
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 構建您的 Compose UI
- 狀態和 Jetpack Compose
- 在 Compose 中儲存 UI 狀態