テキスト フィールド内の電話番号を自動的にフォーマットする

アプリのテキスト フィールドで電話番号を自動的にフォーマットできます。ユーザーが数字を入力するときに電話番号をフォーマットすることで、ユーザーの時間を節約できます。次のガイダンスに沿って、電話番号を自動的にフォーマットします。

  • テキスト フィールドを作成します。
  • テキスト フィールドの数値を自動的に書式設定する。

バージョンの互換性

この実装では、プロジェクトの 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)
    )
}

コードに関する主なポイント

  • onValueChange が正規表現を使用して数値以外の文字をすべて削除し、長さを最大 10 文字に制限してから phoneNumber の状態を更新する TextField コンポーザブル。
  • TextField には、visualTransformation 属性にカスタム 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 オブジェクトには 2 つのメソッドがあります。1 つは元の文字列とフォーマットされた文字列の間のオフセットをマッピングし、もう 1 つは逆マッピングを行います。これらのマッピングにより、ユーザーがテキスト フィールド内のカーソルの位置を変更したときに、書式設定文字をスキップできます。
  • フォーマットされた文字列と phoneNumberOffsetTranslator は、返され、TextField によってフォーマット実行に使用される TransformedText インスタンスの引数として使用されます。

結果

テキスト フィールドに自動的にフォーマットされた電話番号
図 1.テキスト フィールドに自動的にフォーマットされた電話番号。

このガイドを含むコレクション

このガイドは、Android 開発の幅広い目標を網羅する、厳選されたクイックガイド コレクションの一部です。

テキストは UI の主要な構成要素です。アプリでテキストを表示して優れたユーザー エクスペリエンスを提供するさまざまな方法を学びます。
ユーザーがテキストの入力やその他の入力手段を使用してアプリを操作できるようにする方法について学びます。

ご質問やフィードバックがある場合

よくある質問のページでクイックガイドをご覧になるか、お問い合わせフォームからご意見をお寄せください。