Когда я впервые вставляю номер телефона, событие onPaste запускается, как и ожидалось, и проверка/форматирование работает отлично.
Однако, если я удалю все символы и вставлю снова, поведение, похоже, переключится на событие onInput вместо onPaste, что нарушит желаемую функциональность.
Мне бы хотелось операция вставки, чтобы всегда вызывать событие onPaste независимо от состояние EditText.
Я пробовал следующие вещи.
[*]Реализовал TextWatcher для отслеживания изменений в EditText. .
[*]Переопределен onTextChanged для обработки форматирования при изменении ввода.
[*]Попытка использовать ClipboardManager для обнаружения событий вставки.
< /ol>
Код: Выделить всё
class AccountNumberWatcher(
private val editText: EditText,
private val onInvalidPhoneNumber: (() -> Unit)? = null
) : TextWatcher {
private var isUpdating = false
private var isPasteAction = false
private val MAX_LENGTH_SHORT = 12
private val MAX_LENGTH_LONG = 15
init {
editText.setOnTouchListener { _, event ->
if (event.action == android.view.MotionEvent.ACTION_DOWN) {
isPasteAction = isPasteDetected()
}
false
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable?) {
if (isUpdating) return
val originalText = s?.toString() ?: return
// If it's a paste action, we handle it differently
if (isPasteAction) {
handlePasteAction(originalText)
} else {
handleInputAction(originalText)
}
// Reset the paste action flag
isPasteAction = false
}
private fun handlePasteAction(originalText: String) {
val formattedNumber = AppUtils.formatMobileNo(originalText)
val maxLength = if (formattedNumber.length > MAX_LENGTH_SHORT) MAX_LENGTH_LONG else MAX_LENGTH_SHORT
editText.filters = arrayOf(InputFilter.LengthFilter(maxLength))
if (formattedNumber != originalText) {
isUpdating = true
editText.setText(formattedNumber)
editText.setSelection(formattedNumber.length)
isUpdating = false
}
if (formattedNumber.length > MAX_LENGTH_SHORT) {
onInvalidPhoneNumber?.invoke()
}
}
private fun handleInputAction(originalText: String) {
val formattedNumber = AppUtils.formatMobileNo(originalText)
val maxLength = if (formattedNumber.length > MAX_LENGTH_SHORT) MAX_LENGTH_LONG else MAX_LENGTH_SHORT
editText.filters = arrayOf(InputFilter.LengthFilter(maxLength))
if (formattedNumber != originalText) {
isUpdating = true
editText.setText(formattedNumber)
editText.setSelection(formattedNumber.length)
isUpdating = false
}
if (formattedNumber.length > MAX_LENGTH_SHORT) {
onInvalidPhoneNumber?.invoke()
}
}
// Check if the clipboard contains text, indicating a paste action
private fun isPasteDetected(): Boolean {
val clipboard = editText.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
return clipboard.hasPrimaryClip() && clipboard.primaryClip?.getItemAt(0)?.text != null
}
}
//in fragment
binding.etContactSearch.addTextChangedListener(
PhoneNumberWatcher(binding.etContactSearch){
AppUtils.showSnackBar(binding.root, getString(R.string.message_error_phone_number))
}
)
Будем очень признательны за любую информацию или примеры кода.
Подробнее здесь: https://stackoverflow.com/questions/792 ... er-validat
Мобильная версия