Naografix
Naografix

Reputation: 959

Android: EditText with max decimal and max number

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

Answers (2)

prem
prem

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

Muhammad Ashraf
Muhammad Ashraf

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

Related Questions