撰写 OutlinedTextField 电话号码

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

我希望有人能帮助我。 问题:

  • 在 Compose 中使用 OutlinedTextField 来接受电话号码输入。
  • 需要根据国家/地区的电话号码模式格式化电话号码。
  • 格式化后,光标不再位于电话号码末尾。 尝试的解决方案 在输入末尾添加了带有选择 TextRange 的 TextFieldValue。 尝试的解决方案存在问题 防止用户移动光标。

请求帮助: 寻找有关如何允许用户移动光标的建议。 还需要确保如果用户根据国家/地区的格式输入有效的数字,则光标设置到末尾。

电话号码输入:

@Composable
fun PhoneNumberInput(
    phoneNumber: String,
    modifier: Modifier = Modifier,
    internationalCode: InternationalCode,
    onPhoneNumberChanged: (String) -> Unit,
) {
    var textFieldValue by remember {
        mutableStateOf(
            TextFieldValue(
                text = phoneNumber,
                selection = TextRange(phoneNumber.length)
            )
        )
    }
  

    fun onValueChange(newValue: TextFieldValue) {
        val text = newValue.text
        val unformatted = removePhoneNumberFormat(text)
        val formatted = phoneNumberUtil.formatNationalOrNull(text, internationalCode) ?: unformatted
        if (textFieldValue.text==text){
            return
        }

        // Update the state with the formatted text and adjusted cursor position
        textFieldValue = TextFieldValue(
            text = formatted,
            selection = TextRange(unformatted.length)
        )
        onPhoneNumberChanged(unformatted)
    }


    Row(
        modifier = modifier,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Column {
            Box {
                BasicTextField(
                    value = textFieldValue,
                    onValueChange = ::onValueChange,
                    modifier = Modifier.fillMaxWidth().focusRequester(focusRequest),
                    interactionSource = interactionSource,
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone, imeAction = ImeAction.Done),
                    enabled = true,
                    singleLine = true,
                )
            }
        }
    }
}
internal fun removePhoneNumberFormat(value: String): String =
    value.replace(" ", "")
        .replace("-", "")
        .replace(")", "")
        .replace("(", "")

我正在使用 Google 的 libphonenumber 来格式化输入:

实际类 PhoneNumberUtil { private valphoneNumberUtil = getInstance()

actual fun formatInternationalOrNull(phoneNumber: String, internationalCode: InternationalCode): String? = try {
    val number = phoneNumberUtil.parse(phoneNumber, internationalCode.isoCode)
    phoneNumberUtil.format(number, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL)
} catch (e: Exception) {
    null
}

actual fun isValidPhoneNumber(phoneNumber: String, internationalCode: InternationalCode): Boolean = try {
    val number = phoneNumberUtil.parse(phoneNumber, internationalCode.isoCode)
    phoneNumberUtil.isValidNumber(number)
} catch (e: Exception) {
    false
}

actual fun parseOrNull(phoneNumber: String, internationalCode: InternationalCode): String? = try {
    val number = phoneNumberUtil.parse(phoneNumber, internationalCode.isoCode)
    phoneNumberUtil.format(number, PhoneNumberUtil.PhoneNumberFormat.E164)
} catch (e: Exception) {
    null
}

actual fun formatNationalOrNull(
    phoneNumber: String,
    internationalCode: InternationalCode
): String? = try {
    val number = phoneNumberUtil.parse(phoneNumber, internationalCode.isoCode)
    phoneNumberUtil.format(number, PhoneNumberUtil.PhoneNumberFormat.NATIONAL)
} catch (e: Exception) {
    null
}

}

kotlin android-jetpack-compose android-jetpack
1个回答
0
投票

您可以更新

onValueChange
功能以在格式化电话号码时保留光标位置。主要问题是您直接根据未格式化的文本长度设置光标位置,这会阻止用户自由移动光标。

要解决此问题,您可以像这样修改您的

onValueChange
函数:

  1. 保持光标相对于格式化文本的位置。
  2. 即使在格式化后也保留光标位置。
fun onValueChange(newValue: TextFieldValue) {
    val text = newValue.text
    val unformatted = removePhoneNumberFormat(text)
    val formatted = phoneNumberUtil.formatNationalOrNull(text, internationalCode) ?: unformatted

    if (textFieldValue.text == text) {
        return
    }

    // Calculate the cursor position relative to the formatted text
    val cursorPosition = newValue.selection.min
    val adjustedCursorPosition = formatted.take(cursorPosition).length

    textFieldValue = TextFieldValue(
        text = formatted,
        selection = TextRange(adjustedCursorPosition)
    )

    onPhoneNumberChanged(unformatted)
}

这将允许用户自由移动光标,同时还确保根据格式化的电话号码将光标设置到正确的位置。

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