Jetpack 撰写。如何使用掩码格式化输入的电话号码?

问题描述 投票:0回答:1

我正在尝试实现视觉转换以显示带有掩码的格式化电话号码。

问题在于掩码是动态的,可以从后端接收,具体取决于客户端已经输入的字符,所以接收需要一些时间。

这是我的视觉变换:

class PhoneVisualTransformation(val mask: String) :
    VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {
        val source = text.text
        val formattedPhone = source.formatByMask(mask = mask)

        return TransformedText(
            text = AnnotatedString(source),
            offsetMapping = offsetFilter(text = formattedPhone),
        )
    }

    private fun offsetFilter(text: String): OffsetMapping {
        val numberOffsetTranslator = object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                val transformedOffsets = text
                    .mapIndexedNotNull { index, c ->
                        index
                            .takeIf { !isFormattingCharacter(c) }
                            ?.plus(1)
                    }.let { offsetList ->
                        listOf(0) + offsetList
                    }

                return transformedOffsets[offset]
            }

            override fun transformedToOriginal(offset: Int): Int {
                return text
                    .mapIndexedNotNull { index, c ->
                        index.takeIf { isFormattingCharacter(c) }
                    }
                    .count { separatorIndex ->
                        separatorIndex < offset
                    }
                    .let { separatorCount ->
                        offset - separatorCount
                    }
            }
        }

        return numberOffsetTranslator
    }

    private fun isFormattingCharacter(char: Char): Boolean {
        return listOf('(', ')', '-', ' ').any { char == it }
    }
}

formatByMask
是使用redmadrobot输入掩码库的扩展。

 InputTextField(
            modifier = modifier,
            input = state.phone,
            visualTransformation = PhoneVisualTransformation(
                mask = state.mask,
            ),
            onValueChange = {
                viewModel.onValueChange(it)
            },
        ) 

还有我的视图模型:

fun onValueChange(newValue: String) {
  viewModelScope.launch {
    val phoneDetials = getPhoneDetailsByInput(newValue)
    _state.update {
       it.copy(phone = phoneDetails.phone, mask = phoneDetails.mask)
    }
}

} }

getPhoneDetailsByInput() 是挂起函数,它从后端返回掩码。 问题是我的 OffsetMapping 中的偏移量始终为 0。

我做错了什么?也许我完全采取了错误的方法。请帮助我。

android android-jetpack-compose android-viewmodel android-compose-textfield
1个回答
0
投票
fun formatPhoneNumber(phoneNumber: String): String {
    // Remove all non-digit characters
    val digits = phoneNumber.filter { it.isDigit() }

    // Apply formatting
    return buildString {
        for (i in digits.indices) {
            when (i) {
                0 -> append('(')
                3 -> append(") ")
                6 -> append('-')
            }
            append(digits[i])
            if (i == 9) break // no more digits
        }
    }
}

然后撰写

@Composable

有趣的电话号码文本字段(){ var 电话号码 by Remember { mutableStateOf("") }

TextField(
    value = phoneNumber,
    onValueChange = { 
        val formatted = formatPhoneNumber(it)
        if (formatted.length <= 14) { // (123) 456-7890 is 14 characters long
            phoneNumber = formatted
        }
    },
    label = { Text("Phone Number") },
    // Add other TextField properties as needed
)

}

© www.soinside.com 2019 - 2024. All rights reserved.