在文字欄位中自動格式化電話號碼

您可以在應用程式的文字欄位中自動設定電話號碼格式,讓使用者在輸入數字時,系統自動設定電話號碼格式,節省時間。請按照這項指引 自動設定電話號碼格式:

  • 建立文字欄位。
  • 自動設定文字欄位中的數字格式。

版本相容性

這項實作作業需要將專案 minSDK 設為 API 級別 21 以上。

依附元件

建立文字欄位

首先,請設定 TextField。這個範例顯示根據北美電話號碼格式規範 (NANP) 格式化的電話號碼。NanpVisualTransformation 會將原始數字字串格式化為 NANP,例如:1234567890 變更為 (123) 456-7890。

@Composable
fun PhoneNumber() {
    var phoneNumber by rememberSaveable { mutableStateOf("") }
    val numericRegex = Regex("[^0-9]")
    TextField(
        value = phoneNumber,
        onValueChange = {
            // Remove non-numeric characters.
            val stripped = numericRegex.replace(it, "")
            phoneNumber = if (stripped.length >= 10) {
                stripped.substring(0..9)
            } else {
                stripped
            }
        },
        label = { Text("Enter Phone Number") },
        visualTransformation = NanpVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
    )
}

程式碼重點

  • TextField 可組合函式,其中 onValueChange 使用規則運算式移除所有非數字字元,並將長度限制為最多 10 個字元,然後更新 phoneNumber 狀態。
  • TextFieldvisualTransformation 屬性已設定自訂 VisualTransformation 例項。NanpVisualTransformation 是在此處例項化的自訂類別,定義於下一節。

自動格式化文字欄位中的數字

如要格式化原始數字字串,請使用自訂 NanpVisualTransformation 類別的實作項目:

class NanpVisualTransformation : VisualTransformation {

    override fun filter(text: AnnotatedString): TransformedText {
        val trimmed = if (text.text.length >= 10) text.text.substring(0..9) else text.text

        var out = if (trimmed.isNotEmpty()) "(" else ""

        for (i in trimmed.indices) {
            if (i == 3) out += ") "
            if (i == 6) out += "-"
            out += trimmed[i]
        }
        return TransformedText(AnnotatedString(out), phoneNumberOffsetTranslator)
    }

    private val phoneNumberOffsetTranslator = object : OffsetMapping {

        override fun originalToTransformed(offset: Int): Int =
            when (offset) {
                0 -> offset
                // Add 1 for opening parenthesis.
                in 1..3 -> offset + 1
                // Add 3 for both parentheses and a space.
                in 4..6 -> offset + 3
                // Add 4 for both parentheses, space, and hyphen.
                else -> offset + 4
            }

        override fun transformedToOriginal(offset: Int): Int =
            when (offset) {
                0 -> offset
                // Subtract 1 for opening parenthesis.
                in 1..5 -> offset - 1
                // Subtract 3 for both parentheses and a space.
                in 6..10 -> offset - 3
                // Subtract 4 for both parentheses, space, and hyphen.
                else -> offset - 4
            }
    }
}

程式碼重點

  • filter() 函式會在適當位置插入非數字格式字元。
  • phoneNumberOffsetTranslator 物件包含兩種方法。一個會對應原始字串和格式化字串之間的位移,另一個則會執行反向對應。使用者在文字欄位中變更游標位置時,這些對應可略過格式字元。
  • 格式化字串和 phoneNumberOffsetTranslator 會做為引數,用於 TransformedText 例項,該例項會傳回並由 TextField 用於執行格式化作業。

結果

文字欄位中自動格式化的電話號碼
圖 1. 文字欄位中自動格式化的電話號碼。

包含本指南的集合

本指南是精選快速指南系列的一部分,涵蓋更廣泛的 Android 開發目標:

文字是所有 UI 的核心。瞭解在應用程式中呈現文字的不同方式,提供令人愉悅的使用者體驗。
瞭解如何實作使用者與應用程式互動的方式,包括輸入文字及使用其他輸入方式。

如有問題或想提供意見

前往常見問題頁面,瞭解快速指南或與我們聯絡,分享您的想法。