Created
November 2, 2022 16:51
-
-
Save NightlyNexus/9e9afaffa411f54fcfddad9874dd596a to your computer and use it in GitHub Desktop.
An Android InputFilter for a decimal range
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.text.InputFilter | |
import android.text.Spanned | |
class RangeInputFilter(private val min: Int, private val max: Int) : InputFilter { | |
override fun filter( | |
source: CharSequence, | |
start: Int, | |
end: Int, | |
dest: Spanned, | |
dstart: Int, | |
dend: Int | |
): CharSequence? { | |
if (start == end) { | |
// Always allow the empty replacement. | |
return null | |
} | |
var realStart = start | |
if (dstart == 0) { | |
while (source[realStart] == '0') { | |
realStart++ | |
if (realStart == end) { | |
// Minor optimization when the replacement text is all preceding 0s. | |
return "" | |
} | |
} | |
} | |
val resultLength = dstart + end - realStart + dest.length - dend | |
val result = StringBuilder(resultLength) | |
.append(dest, 0, dstart) | |
.append(source, realStart, end) | |
.append(dest, dend, dest.length) | |
.toString() | |
return try { | |
val input = result.toInt() | |
if (input in min..max) { | |
if (realStart == start) { | |
// Accept the new input. | |
null | |
} else { | |
// Accept the new input without the preceding 0s. | |
source.subSequence(realStart, end) | |
} | |
} else { | |
// Reject the new input and return to the original text. | |
dest.subSequence(dstart, dend) | |
} | |
} catch (e: NumberFormatException) { | |
// Reject the new input and return to the original text. | |
dest.subSequence(dstart, dend) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment