I want to define a min and max value for an EditText
.
For example: if any person tries to enter a month value in it, the value must be between 1-12.
I extended @Pratik Sharmas code to use BigDecimal objects instead of ints so that it can accept larger numbers, and account for any formatting in the EditText that isn't a number (like currency formatting i.e. spaces, commas and periods)
EDIT: note that this implementation has 2 as the minimum significant figures set on the BigDecimal (see the MIN_SIG_FIG constant) as I used it for currency, so there was always 2 leading numbers before the decimal point. Alter the MIN_SIG_FIG constant as necessary for your own implementation.
public class InputFilterMinMax implements InputFilter {
private static final int MIN_SIG_FIG = 2;
private BigDecimal min, max;
public InputFilterMinMax(BigDecimal min, BigDecimal max) {
this.min = min;
this.max = max;
}
public InputFilterMinMax(String min, String max) {
this.min = new BigDecimal(min);
this.max = new BigDecimal(max);
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
int dend) {
try {
BigDecimal input = formatStringToBigDecimal(dest.toString()
+ source.toString());
if (isInRange(min, max, input)) {
return null;
}
} catch (NumberFormatException nfe) {
}
return "";
}
private boolean isInRange(BigDecimal a, BigDecimal b, BigDecimal c) {
return b.compareTo(a) > 0 ? c.compareTo(a) >= 0 && c.compareTo(b) <= 0
: c.compareTo(b) >= 0 && c.compareTo(a) <= 0;
}
public static BigDecimal formatStringToBigDecimal(String n) {
Number number = null;
try {
number = getDefaultNumberFormat().parse(n.replaceAll("[^\\d]", ""));
BigDecimal parsed = new BigDecimal(number.doubleValue()).divide(new BigDecimal(100), 2,
BigDecimal.ROUND_UNNECESSARY);
return parsed;
} catch (ParseException e) {
return new BigDecimal(0);
}
}
private static NumberFormat getDefaultNumberFormat() {
NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
nf.setMinimumFractionDigits(MIN_SIG_FIG);
return nf;
}