Text 用於顯示文字,若是要讓使用者輸入文字呢?這時就會需要表單元件 TextField。在看完跟 Text 相關的元件後,我們接著看 TextField。今天的耕讀筆記就以此為主題做研究。
TextField 元件由於 Compose 的設計核心希望讓每一個元件都能彼此獨立,加上 Declarative 的特性,因此在宣告 TextField 元件時,有幾點需要注意:
remember() 搭配 mutableStateOf() 後,以 value 參數傳入 TextField。onValueChange 事件,並將輸入框內的文字設定到 value 以更新 UI 顯示。Text 元件傳入 label 參數。var text by remember { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Username") }
)
除了以上三個常用的參數外,TextField 元件還提供許多設定:
modifier:調整 TextField 屬性。enabled:是否啟用輸入框,預設為 true,若設為 false 則輸入框不能編輯且不可設為焦點。readOnly:是否唯讀,預設為 false,若設為 true 則輸入框不能編輯但可設為焦點且可複製其中的文字。textStyle:設定輸入框內的文字樣式。placeholder:設定當焦點放在輸入框上且輸入框內沒有文字時顯示的替代文字。leadingIcon:設定在輸入框前面顯示的圖示。trailingIcon:設定在輸入框後面顯示的圖示。isError:設定輸入框目前的輸入值是否有誤,若為 true 時,會有顯示上的變化。visualTransformation:設定將輸入框內的文字做視覺轉換。keyboardOptions:設定彈出的鍵盤類型。keyboardActions:設定當輸入服務發出 IME 事件時的 Event Handler。singleLine:設定輸入框是否只能輸入一行。maxLines:設定輸入框能輸入的最大行數。interactionSource:設定監聽元件狀態。shape:設定輸入框的形狀。colors:設定輸入框的顏色。TextField 的外顯樣式我們可以透過兩種方式來設定 TextField 的外顯樣式,一種是設定 textStyle 參數、另一種是設定 modifier 參數:
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)
)
在上面的例子裡,我們設定輸入框只能顯示兩行、文字顏色為藍色粗體以及內距間隔 20 dp。
填寫表單遇到密碼欄位時,我們一般會暫時將密碼的值以符號取代,達成遮蔽的效果。這在 TextField 裡可以透過 visualTransformation 及 keyboardOptions 參數來設定:
var password by remember { mutableStateOf("") }
TextField(
    value = password,
    onValueChange = { password = it },
    label = { Text("Password") },
    visualTransformation = PasswordVisualTransformation(),
    keyboardOptions =  KeyboardOptions(keyboardType = KeyboardType.Password)
)
將 PasswordVisualTransformation 傳入 visualTransformation 參數後,輸入框內的文字就會以遮蔽的字元顯示。KeyboardOptions 則是可設定彈出的螢幕類型,不過在 Desktop 上一般都是用實體鍵盤,有無設定這個參數感覺不出差異。不過還是順道提一下 KeyboardOptions 支援的鍵盤類型:
Text
Ascii
Number
Phone
Uri
Email
Password
NumberPassword
onValueChange 事件透過註冊 TextField 的 onValueChange 事件,可以讓我們在使用者輸入時,取得輸入框的內容,讓我們可以對輸入框的內容做二次處理。比方說把輸入框裡的特定字元取代成其他內容。
var value by remember { mutableStateOf("") }
TextField(
    value = value,
    onValueChange = { text ->
        value = text.replace('0', '*')
    },
    label = { Text("Enter text") },
)
OutlinedTextField 元件其實 TextField 元件有兩種風格,一種是預設灰色的 TextField,另一種是有顏色外框的 OutlinedTextField。不過兩者的行為及支援的設定值差異不大:
OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Username") },
)
值得一提的是,TextField 元件是最常使用的文字輸入框,其遵循著 Material Design 設計準則,足以應付大多數的開發情況,若你需要客製化輸入框的更多細節,可以用 TextField 的低階元件 BasicTextField。