I want to prevent the user to write more than one dot "." and prevent him to write a dot "." in the beginning.
et_cm.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (et_cm.hasFocus()) {
if(et_cm.text.isEmpty()){
et_inches.setText("0")
}else{
val inch = ConvertCmToInch(et_cm.text.toString().toDouble()).toString()
et_inches.setText(inch)
}
}
}
override fun afterTextChanged(s: Editable) {}
})
<EditText
android:id="@ id/et_cm"
android:layout_width="113dp"
android:layout_height="48dp"
android:digits="1234567890."
android:ems="10"
android:hint="@string/cm"
android:inputType="numberDecimal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.677"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.415" />
I've tried to add this in the if but the application went down when I tested it:
et_cm.text.isEmpty() || et_cm.text.equals("^\\.")
CodePudding user response:
Put your code that enforces the text in afterTextChanged
. It is simpler to use if you aren't scrutinizing which specific characters are changing from which specific previous characters. You could also move your existing code into this function, which I did in the example below. I also simplified your code.
Only set the changed text if you actually changed it, or there will be an infinite loop.
This code also attempts to preserve the cursor position. Otherwise it would jump to the beginning when there is a change. I didn't bother to make it sophisticated enough to preserve it correctly for every conceivable possible change.
It checks for dots using while loops instead of if
because the user might be pasting text that includes more than one unwanted character. You could also possibly do this using Regex, but I think that would make it harder to preserve cursor position and it would lose formatting in the CharSequence if there were any, although that's not usually a concern for user-entered text.
override fun afterTextChanged(s: Editable) {
var outS = s
var removedChars = 0
val cursorPosition = etCm.selectionStart
while (outS.startsWith('.')) {
outS = outS.delete(0, 1)
removedChars
}
while (outS.count { it == '.' } > 1) {
val index = outS.lastIndexOf('.')
outS = outS.delete(index, index 1)
removedChars
}
if (s != outS) {
etCm.text = outS
etCm.setSelection(cursorPosition - removedChars)
} else if (etCm.hasFocus()) {
etInches.text = ConvertCmToInch(s.toString().toDoubleOrNull() ?: 0.0).toString()
}
}