Skip to content

Commit 0346b45

Browse files
committed
Merge pull request #339 from android/auto-format-phone-number
Auto format phone number
2 parents 6ea91d1 + a508b14 commit 0346b45

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package com.example.compose.snippets.images
2+

compose/snippets/src/main/java/com/example/compose/snippets/text/TextSnippets.kt

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import androidx.compose.ui.graphics.Color.Companion.Cyan
5252
import androidx.compose.ui.graphics.Shadow
5353
import androidx.compose.ui.platform.LocalUriHandler
5454
import androidx.compose.ui.res.stringResource
55+
import androidx.compose.ui.text.AnnotatedString
5556
import androidx.compose.ui.text.LinkAnnotation
5657
import androidx.compose.ui.text.ParagraphStyle
5758
import androidx.compose.ui.text.PlatformTextStyle
@@ -64,7 +65,10 @@ import androidx.compose.ui.text.font.FontFamily
6465
import androidx.compose.ui.text.font.FontStyle
6566
import androidx.compose.ui.text.font.FontWeight
6667
import androidx.compose.ui.text.input.KeyboardType
68+
import androidx.compose.ui.text.input.OffsetMapping
6769
import androidx.compose.ui.text.input.PasswordVisualTransformation
70+
import androidx.compose.ui.text.input.TransformedText
71+
import androidx.compose.ui.text.input.VisualTransformation
6872
import androidx.compose.ui.text.style.Hyphens
6973
import androidx.compose.ui.text.style.LineBreak
7074
import androidx.compose.ui.text.style.LineHeightStyle
@@ -765,6 +769,72 @@ fun BasicMarqueeSample() {
765769
}
766770
// [END android_compose_text_marquee]
767771

772+
// [START android_compose_text_auto_format_phone_number_textfieldconfig]
773+
@Composable
774+
fun PhoneNumber() {
775+
var phoneNumber by rememberSaveable { mutableStateOf("") }
776+
val numericRegex = Regex("[^0-9]")
777+
TextField(
778+
value = phoneNumber,
779+
onValueChange = {
780+
// Remove non-numeric characters.
781+
val stripped = numericRegex.replace(it, "")
782+
phoneNumber = if (stripped.length >= 10) {
783+
stripped.substring(0..9)
784+
} else {
785+
stripped
786+
}
787+
},
788+
label = { Text("Enter Phone Number") },
789+
visualTransformation = NanpVisualTransformation(),
790+
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
791+
)
792+
}
793+
// [END android_compose_text_auto_format_phone_number_textfieldconfig]
794+
795+
// [START android_compose_text_auto_format_phone_number_transformtext]
796+
class NanpVisualTransformation() : VisualTransformation {
797+
798+
override fun filter(text: AnnotatedString): TransformedText {
799+
val trimmed = if (text.text.length >= 10) text.text.substring(0..9) else text.text
800+
801+
var out = if (trimmed.isNotEmpty()) "(" else ""
802+
803+
for (i in trimmed.indices) {
804+
if (i == 3) out += ") "
805+
if (i == 6) out += "-"
806+
out += trimmed[i]
807+
}
808+
return TransformedText(AnnotatedString(out), phoneNumberOffsetTranslator)
809+
}
810+
811+
private val phoneNumberOffsetTranslator = object : OffsetMapping {
812+
813+
override fun originalToTransformed(offset: Int): Int =
814+
when (offset) {
815+
0 -> offset
816+
// Add 1 for opening parenthesis.
817+
in 1..3 -> offset + 1
818+
// Add 3 for both parentheses and a space.
819+
in 4..6 -> offset + 3
820+
// Add 4 for both parentheses, space, and hyphen.
821+
else -> offset + 4
822+
}
823+
824+
override fun transformedToOriginal(offset: Int): Int =
825+
when (offset) {
826+
0 -> offset
827+
// Subtract 1 for opening parenthesis.
828+
in 1..5 -> offset - 1
829+
// Subtract 3 for both parentheses and a space.
830+
in 6..10 -> offset - 3
831+
// Subtract 4 for both parentheses, space, and hyphen.
832+
else -> offset - 4
833+
}
834+
}
835+
}
836+
// [END android_compose_text_auto_format_phone_number_transformtext]
837+
768838
private val firaSansFamily = FontFamily()
769839

770840
val LightBlue = Color(0xFF0066FF)

0 commit comments

Comments
 (0)