diff --git a/views/src/main/java/ru/touchin/widget/AmountWithDecimalEditText.kt b/views/src/main/java/ru/touchin/widget/AmountWithDecimalEditText.kt index 50b955a..54899b1 100644 --- a/views/src/main/java/ru/touchin/widget/AmountWithDecimalEditText.kt +++ b/views/src/main/java/ru/touchin/widget/AmountWithDecimalEditText.kt @@ -7,14 +7,15 @@ import androidx.core.widget.doOnTextChanged import ru.touchin.roboswag.components.views.R import java.text.DecimalFormat import java.text.DecimalFormatSymbols +import kotlin.math.abs import kotlin.math.max import kotlin.math.min import kotlin.math.pow class AmountWithDecimalEditText @JvmOverloads constructor( - context: Context, - attrs: AttributeSet?, - defStyleAttr: Int = R.attr.editTextStyle + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int = R.attr.editTextStyle ) : AppCompatEditText(context, attrs, defStyleAttr) { companion object { @@ -52,28 +53,43 @@ class AmountWithDecimalEditText @JvmOverloads constructor( } if (text == decimalSeparator || text.count { it == decimalSeparator[0] } > 1) { - setText(textBefore) - setSelection(max(cursorPos - 1, 0)) + if (abs(textBefore.length - text.length) > 1) { + setTextWhichWasPasted(text) + } else { + setText(textBefore) + setSelection(max(cursorPos - 1, 0)) + } return@doOnTextChanged } if (text.take(2) == "00") { - setText(textBefore) - setSelection(max(cursorPos - 1, 0)) + if (abs(textBefore.length - text.length) > 1) { + setTextWhichWasPasted(text) + } else { + setText(textBefore) + setSelection(max(cursorPos - 1, 0)) + } return@doOnTextChanged } if (text.length >= 2 && text[0] == '0' && text[1] != decimalSeparator[0]) { - setText(text[1].toString()) - setSelection(max(cursorPos - 1, 0)) + if (abs(textBefore.length - text.length) > 1) { + setTextWhichWasPasted(text) + } else { + setTextWhichWasPasted(text) + setSelection(max(cursorPos - 1, 0)) + } return@doOnTextChanged } - val decimalPartLength_ = text.split(decimalSeparator).getOrNull(1)?.length if (!isSeparatorCutInvalidDecimalLength && decimalPartLength_ != null && decimalPartLength_ > decimalPartLength) { - setText(textBefore) - setSelection(max(cursorPos - 1, 0)) + if (abs(textBefore.length - text.length) > 1) { + setTextWhichWasPasted(text) + } else { + setText(textBefore) + setSelection(max(cursorPos - 1, 0)) + } return@doOnTextChanged } @@ -87,15 +103,10 @@ class AmountWithDecimalEditText @JvmOverloads constructor( setSelection(min(cursorPos + diff, textAfter.length)) } else { if (!textBefore.contains(decimalSeparator) - && textAfter.contains(decimalSeparator) + && textAfter.contains(decimalSeparator) ) { setText(textAfter) - setSelection( - min( - textAfter.length, - textAfter.indexOf(decimalSeparator) + 1 - ) - ) + setSelection(min(textAfter.length, textAfter.indexOf(decimalSeparator) + 1)) return@doOnTextChanged } val diff = textBefore.length - textAfter.length @@ -115,6 +126,28 @@ class AmountWithDecimalEditText @JvmOverloads constructor( } } + private fun setTextWhichWasPasted(text: String) { + var result = "" + var decimalLength = -1 + var index = 0 + while (decimalLength < decimalPartLength && index < text.length) { + if (text[index] == decimalSeparator[0]) { + if (decimalLength == -1 && decimalPartLength != 0) { + decimalLength = 0 + result += text[index] + } else { + break + } + } else { + result += text[index] + } + index++ + } + result = result.formatMoney(decimalPartLength) + setText(result) + setSelection(result.length) + } + fun getTextWithoutFormatting() = text.toString().withoutFormatting() @@ -124,28 +157,33 @@ class AmountWithDecimalEditText @JvmOverloads constructor( return result } + private fun String.prepareForDoubleCast(): String { + var result = this + possibleDecimalSeparators.forEach { + result = result.replace(it, ".") + } + return result.withoutFormatting() + } + private fun isTextErased(textBefore: String, textAfter: String) = - textAfter.length <= textBefore.length + textAfter.length <= textBefore.length private fun String.formatMoney(decimalPartLength_: Int?): String { var mask = COMMON_MONEY_MASK - if (decimalPartLength_ != null && decimalPartLength != 0) mask += "." + "0".repeat( - min( - decimalPartLength_, - decimalPartLength - ) - ) + if (decimalPartLength_ != null && decimalPartLength != 0) { + mask += "." + "0".repeat(min(decimalPartLength_, decimalPartLength)) + } val formatter = DecimalFormat(mask) formatter.decimalFormatSymbols = DecimalFormatSymbols().also { it.decimalSeparator = decimalSeparator[0] it.groupingSeparator = GROUPING_SEPARATOR } - return formatter.format(this.replace(",", ".").toDouble().floor()) + return formatter.format(this.prepareForDoubleCast().toDouble().floor()) } private fun Double.floor() = - (this * 10.toDouble().pow(decimalPartLength)).toLong() / 10.toDouble() - .pow(decimalPartLength) + (this * 10.toDouble().pow(decimalPartLength)).toLong() / 10.toDouble() + .pow(decimalPartLength) -} +} \ No newline at end of file