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

您可以在應用程式的文字欄位中自動設定電話號碼格式,在使用者輸入數字時自動設定電話號碼格式,為使用者節省時間。請按照下列指示自動設定電話號碼格式:

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

版本相容性

這個實作方式需要將專案 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 使用規則運算式移除所有非數字字元,並在更新 phoneNumber 狀態前將長度限制為最多 10 個字元。
  • 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 的核心部分。瞭解在應用程式中顯示文字的不同方式,以提供優質的使用者體驗。
瞭解如何讓使用者透過輸入文字和其他輸入方式與應用程式互動。

有問題或意見回饋嗎?

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