Reputation: 959
I'm trying to create a filter for my edittext to have a max number with max decimal after point. I want to use this editText for money typing.
I set the inputType
to numberDecimal
but I can write infinite number with lot of digits after decimal point.
I found lot of thread on StackOverFlow to filter the max decimal, but I want to add a max number too.
So, I just want to have filter to write between [0 and 1000] with 2 digits after decimal point, but 1000 is the max. (can't write 1000.99).
Thanks
Upvotes: 1
Views: 3805
Reputation: 107
You may use this; it lets edit text only take decimal value up to your chosen places within your min-max range.
class DecimalDigitsInputFilter(digitsBeforeZero: Int, digitsAfterZero: Int, min: Double, max: Double) :
InputFilter {
private val mDigitsBeforeZero: Int
private val mDigitsAfterZero: Int
private var min: Double
private var max: Double
private val mPattern: Pattern
override fun filter(
source: CharSequence,
start: Int,
end: Int,
dest: Spanned,
dstart: Int,
dend: Int
): CharSequence? {
try {
val input = (dest.toString() + source.toString()).toDouble()
val replacement = source.subSequence(start, end).toString()
val newVal = (dest.subSequence(0, dstart).toString() + replacement
+ dest.subSequence(dend, dest.length).toString())
val matcher: Matcher = mPattern.matcher(newVal)
if (matcher.matches() && isInRange(min,max,input)) return null
return if (TextUtils.isEmpty(source)) dest.subSequence(dstart, dend) else ""
}catch (e : Exception){}
return ""
}
init {
this.min = min
this.max = max
this.mDigitsAfterZero = digitsAfterZero
this.mDigitsBeforeZero = digitsBeforeZero
mPattern = Pattern.compile(
"-?[0-9]{0," + mDigitsBeforeZero + "}+((\\.[0-9]{0," + mDigitsAfterZero
+ "})?)||(\\.)?"
)
}
private fun isInRange(a: Double, b: Double, c: Double): Boolean {
return if (b > a) c in a..b else c in b..a
}
}
And then can set this filter to your edit text:
binding.editText.filters = arrayOf(DecimalDigitsInputFilter(2,3,0.0,100.0))
Upvotes: 0
Reputation: 1282
You can achieve that using InputFilters
first you need to create an input filter for the decimal digits
public class DecimalDigitsInputFilter implements InputFilter {
Pattern mPattern;
public DecimalDigitsInputFilter(int digitsBeforeZero,int digitsAfterZero) {
mPattern=Pattern.compile("[0-9]{0," + (digitsBeforeZero-1) + "}+((\\.[0-9]{0," + (digitsAfterZero-1) + "})?)||(\\.)?");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
Matcher matcher=mPattern.matcher(dest);
if(!matcher.matches())
return "";
return null;
}
}
Then create another input filter to limit numbers between 0 and 1000
public class InputFilterMinMax implements InputFilter {
private int min, max;
public InputFilterMinMax(int min, int max) {
this.min = min;
this.max = max;
}
public InputFilterMinMax(String min, String max) {
this.min = Integer.parseInt(min);
this.max = Integer.parseInt(max);
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (isInRange(min, max, input))
return null;
} catch (NumberFormatException nfe) { }
return "";
}
private boolean isInRange(int a, int b, int c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}
then set these input filters to your edit text
edittext.setFilters(new InputFilter[]{ new InputFilterMinMax("0", "1000"), new DecimalDigitsInputFilter(3,2)});
I haven't tried the code but I think this will put you on the right way.
References:
Limit Decimal Places in Android EditText
Is there a way to define a min and max value for EditText in Android?
Upvotes: 3