我希望有人能帮助我。 问题:
请求帮助: 寻找有关如何允许用户移动光标的建议。 还需要确保如果用户根据国家/地区的格式输入有效的数字,则光标设置到末尾。
电话号码输入:
@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
}
}
您可以更新
onValueChange
功能以在格式化电话号码时保留光标位置。主要问题是您直接根据未格式化的文本长度设置光标位置,这会阻止用户自由移动光标。
要解决此问题,您可以像这样修改您的
onValueChange
函数:
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)
}
这将允许用户自由移动光标,同时还确保根据格式化的电话号码将光标设置到正确的位置。