1

Is there a way to only allow numbers x through y to be entered in a EditText dynamically?

I.E don't even allow a number below x or above y to be entered? For example x = 1 y = 12.

Of course i could solve this in Java after the user hit submit with the invalid numbers and prompt them to enter again. It's a time waster though.

Something like android:digits="01234..." but being able to specify n-th fields.

e.g

  • A range going from 1 to 12

The user should not get confused since they are entering a month number.

I am already using android:maxLength="2" but i need finer control.

Supercan
  • 305
  • 1
  • 6
  • 14
  • 1
    refer [Is there a way to define a min and max value for EditText in Android?](http://stackoverflow.com/questions/14212518/is-there-a-way-to-define-a-min-and-max-value-for-edittext-in-android) – Ravi Jan 06 '17 at 12:12
  • You'll need to attach a listener to your EditText and validate the input in real-time. – Bradley Wilson Jan 06 '17 at 12:15
  • My answer will validate your `EditText` with **all your requirement**! – Jagruttam Panchal Jan 06 '17 at 14:43

5 Answers5

1

It's a bit crude (given that I wrote it quickly) but could do something like this. I would remove the onClick method and create an OnFocusChangeListener and put the code in there.

Also from what it looks like you want something that checks Input as it's being entered and I don't really know if that's possible for a set range let alone that it'll probably cause the app to lag. As suggested by others, validation after Input is the logical route.

enter image description here

public void ValidateInputClick(View view) {

    int Min = 1;
    int Max = 12;

    final TextInputLayout EditTextIP = (TextInputLayout) findViewById(R.id.layoutInput);
    String str = EditTextIP.getEditText().getText().toString();


    if (str.equals("") || str.contains("\n")) {
        EditTextIP.setError("Cannot be blank");
        EditTextIP.setErrorEnabled(true);
    }
    else {
        int inputToInt = Integer.parseInt(str);

        if (inputToInt >= Min && inputToInt <= Max) {

            //Show number
            Snackbar.make(view, str, Snackbar.LENGTH_SHORT).show();
            EditTextIP.setErrorEnabled(false);

        } else {
            //Clear text
            EditTextIP.getEditText().setText("");
            //Show Error
            EditTextIP.setError("Number must be between 1-12");
            EditTextIP.setErrorEnabled(true);
        }
    }

}

XML:

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/layoutInput">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText1"
        android:hint="Please enter a number between 1 and 12"
        android:maxLength="2"
        android:onClick="ValidateInputClick"/>

</android.support.design.widget.TextInputLayout>
Greg432
  • 530
  • 4
  • 25
1

No need to do anything in xml.

Find EditText in code:

int minValue = 1;
int maxValue = 12;

EditText input = (EditText) findViewById(R.id.txtInput);
input.setInputType(InputType.TYPE_CLASS_NUMBER);
input.setFilters(new InputFilter[]
    {
        new InputFilterMinMax(minValue, maxValue), 
        new InputFilter.LengthFilter(String.valueOf(maxValue).length())
    });
input.setKeyListener(DigitsKeyListener.getInstance("0123456789"));

Code for InputFilterMinMax:

public class InputFilterMinMax implements InputFilter {

    private int min, max;

    public InputFilterMinMax(int min, int max) {
        this.min = min;
        this.max = 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) {
            nfe.printStackTrace();
        }
        return "";
    }

    private boolean isInRange(int a, int b, int c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }
}

Hope will help you!

Jagruttam Panchal
  • 3,152
  • 2
  • 15
  • 21
0

I suggest that you still go for validation after Input. This is simply logical, if you put yourself in End-User position. The user will try to tap "99", yet you do not allow second digit to be more than 5. Are you planning to somehow edit they soft-keyboard to only display certain numbers in keyboard? That's waaay more confusing and time consuming. Same would be with writting WARNING / INSTRUCTION messages uppon user trying to write invalid number (= in this case you are anyway doing validation in background.

Check this SO answer for accessing certain digits in int:

And uppon entry just check for the 2nd digit, hence you allow for the first one to be from 1-9 (which is all).

if(secondDigit > 5){

// Warn the user of incorrect input

}
Community
  • 1
  • 1
David Kasabji
  • 1,049
  • 3
  • 15
  • 32
  • Thank you for your answer, what i meant to say more clearly is a more logical range of numbers from 1 to 12. – Supercan Jan 06 '17 at 12:27
  • The range is a bit weird, since digits go to from 1-9. Or do you mean that you would like to accept input number from 1-12. Then it's easier, you don't even need to check each digit, just check the input value if it's in your criteria. But if you do want to check certain digits, just apply above answer, for any digit (index) position in integer. – David Kasabji Jan 06 '17 at 12:34
0

you can use Textwatcher for this.

please look at below code. In onTextChanged you can get which character is entered and count of Character entered.

TextWatcher textwatcher = getMandatoryTextWatcher(editText);
String text = editText.getText().toString();//At this point String text is not empty.

editText.addTextChangedListener(textwatcher);

public TextWatcher getMandatoryTextWatcher(final EditText editText) {
    TextWatcher textwatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void afterTextChanged(Editable s) {
            try {
                //The first time this is called(the first softkey backspace press),
                //text is empty. This causes a weird issue where the character that 
                //was just removed by pressing the backspace, reappears again. 
                //This is only the first time.

                String text = editText.getText().toString();

                if (text.length() <= 0) {
                    editText.setError(errorMandatory);

                } else if (text.length() > 0) {
                    editText.setError(null);
                } else {
                    editText.setError(errorMelding);
                }
           } catch (NumberFormatException nfe) {
                    editText.setError(errorMeldingTijdensParsen);
        }
    }
};
return textwatcher;
}

you can use something like this. Hope this help you.

Nitesh Rathod
  • 368
  • 3
  • 15
0

If your range is short and you don't need double numbers , I recommend you to use spinner for selecting numbers.

Mans
  • 114
  • 1
  • 13