android 美国电话号码合成中的可视化转换

x7rlezfr  于 2023-03-27  发布在  Android
关注(0)|答案(1)|浏览(474)

我想在用户输入字段时添加电话号码格式。到目前为止,它可以正常工作,但是当字段为空时,光标会在错误的位置。当我们有初始值时,它会将光标移动到正确的位置。
注:我想提供支持,以增加数字之间的字符。
Reference here
电话:1234567890 -〉+1(123)456-7890
当为空时-〉+1
类型1 -〉+1(1
类型2 -〉+1(12
类型3 -〉+1(123)
我想只显示+1时,字段为空,如果用户类型的第一个字符,我想添加(。
这是我的努力。

/**
 * The visual filter for phone number.
 *
 * This filter converts up to 10 digits to phone number form.
 * For example, "1234567890" will be shown as "+1 (123) 456-7890".
 */
private val phoneNumberFilter = VisualTransformation { text ->

    // +1 (XXX) XXX-XXXX
    val trimmed = if (text.text.length >= 10) text.text.substring(0..9) else text.text
    var out = ""

    for (i in trimmed.indices) {
        out += trimmed[i]
        when (i) {
//                0 -> out+= "$out"
            2 -> out += ") "
            5 -> out += "-"
        }
    }
    out = "+1 ($out"

    val mapping = object : OffsetMapping {
        override fun originalToTransformed(offset: Int): Int {

            Log.d("TAG", "Out: $out")

            val transformedOffsets = out
                .mapIndexedNotNull { index, c ->
                    index
                        .takeIf { c.isDigit() }
                        // convert index to an offset
                        ?.plus(1)
                }
                // We want to support an offset of 0 and shift everything to the right,
                // so we prepend that index by default
                .let { offsetList ->
                    listOf(0) + offsetList
                }

//            val transformedOffsets = offset + countSpecialChars(out) + 1
            Log.d("TAG", "originalToTransformed: $transformedOffsets")
            return transformedOffsets[offset+1]
        }

        override fun transformedToOriginal(offset: Int): Int {

            val originalOffset = out
                // This creates a list of all separator offsets
                .mapIndexedNotNull { index, c ->
                    index.takeIf { !c.isDigit() }
                }
                // We want to count how many separators precede the transformed offset
                .count { separatorIndex ->
                    separatorIndex < offset
                }
                // We find the original offset by subtracting the number of separators
                .let { separatorCount ->
                    offset - separatorCount
                }

//            val originalOffset = offset - countSpecialChars(out) - 1
            Log.d("TAG", "transformedToOriginal: $originalOffset")
            return originalOffset-1
        }

    }

用户界面

OutlinedTextField(
        modifier = Modifier.fillMaxWidth(),
        value = phone,
        onValueChange = { value ->
            if (value.length <= 10) {
                phone = value.takeWhile { it.isDigit() }
            }

            Log.d("TAG", "PhoneNumber: $phone")
        },
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone),
        visualTransformation = remember { phoneNumberFilter }
    )

Check visual here

ubof19bj

ubof19bj1#

您可以用途:

private val phoneNumberFilter = VisualTransformation { text ->

    // +1 (XXX) XXX-XXXX
    val trimmed = if (text.text.length >= 10) text.text.substring(0..9) else text.text
    var out = ""
    if (text.isNotEmpty()) out = "("
    for (i in trimmed.indices) {
        out += trimmed[i]
        when (i) {
            2 -> out += ") "
            5 -> out += "-"
        }
    }
    out = "+1 $out"

    val mapping = object : OffsetMapping {
        override fun originalToTransformed(offset: Int): Int {

            if (offset == 0) return 3
            if (offset <= 2) return offset + 4
            if (offset <= 5) return offset + 6
            return offset + 7

        }

        override fun transformedToOriginal(offset: Int): Int {
            if (offset <=3) return 0
            if (offset <=7) return offset -4
            if (offset <=12) return offset -6
            return offset -7
        }

    }
    TransformedText(AnnotatedString(out), mapping)
}

相关问题