improved past
This commit is contained in:
parent
af7e505bc5
commit
c720619c37
|
|
@ -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)
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue