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.
If you are only concerned about max limit then just add below line in
android:maxLength="10"
If you need to add min limit then you can do like this way in this case min limit is 7. user is restricted to enter character between min and max limit (in between 8 and 10)
public final static boolean isValidCellPhone(String number){
if (number.length() < 8 || number.length() >10 ) {
return false;
} else {
return android.util.Patterns.PHONE.matcher(number).matches();
}
}
If you also need to restrict user to enter 01 at start then modify if condition like this way
if (!(number.startsWith("01")) || number.length() < 8 || number.length() >10 ) {
.
.
.
}
At the end call method like
....else if (!(Helper.isValidMobilePhone(textMobileNo))){
Helper.setEditTextError(etMobileNo,"Invalid Mobile Number");
}......
Of what i've seen of @Patrik's solution and @Zac's addition, the code provided still has a big problem :
If min==3
then it's impossible to type any number starting with 1 or 2 (ex: 15, 23)
If min>=10
then it's impossible to type anything as every number will have to start with 1,2,3...
In my understanding we cannot achieve the min-max limitation of an EditText
's value with simple use of the class InputFilterMinMax
, at least not for the min Value, because when user is typing a positive number, the value goes growing and we can easily perform an on-the-fly test to check if it's reached the limit or went outside the range and block entries that do not comply. Testing the min value is a different story as we cannot be sure if the user has finished typing or not and therefore cannot decide if we should block or not.
It's not exactly what OP requested but for validation purposes i've combined in my solution an InputFilter
to test max values, with an OnFocusChangeListener
to re-test for min value when the EditText
loses the focus assuming the user's finished typing and it's something like this :
package test;
import android.text.InputFilter;
import android.text.Spanned;
public class InputFilterMax implements InputFilter {
private int max;
public InputFilterMax(int max) {
this.max = max;
}
public InputFilterMax(String max) {
this.max = Integer.parseInt(max);
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
String replacement = source.subSequence(start, end).toString();
String newVal = dest.toString().substring(0, dstart) + replacement +dest.toString().substring(dend, dest.toString().length());
int input = Integer.parseInt(newVal);
if (input<=max)
return null;
} catch (NumberFormatException nfe) { }
//Maybe notify user that the value is not good
return "";
}
}
And OnFocusChangeListenerMin
package test;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnFocusChangeListener;
public class OnFocusChangeListenerMin implements OnFocusChangeListener {
private int min;
public OnFocusChangeListenerMin(int min) {
this.min = min;
}
public OnFocusChangeListenerMin(String min) {
this.min = Integer.parseInt(min);
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus) {
String val = ((EditText)v).getText().toString();
if(!TextUtils.isEmpty(val)){
if(Integer.valueOf(val)<min){
//Notify user that the value is not good
}
}
}
}
}
Then in Activity set the InputFilterMax
and theOnFocusChangeListenerMin
to EditText
note : You can 2 both min and max in onFocusChangeListener
.
mQteEditText.setOnFocusChangeListener( new OnFocusChangeListenerMin('20');
mQteEditText.setFilters(new InputFilter[]{new InputFilterMax(getActivity(),'50')});
Kotlin if any one needs it (Use Utilities)
class InputFilterMinMax: InputFilter {
private var min:Int = 0
private var max:Int = 0
constructor(min:Int, max:Int) {
this.min = min
this.max = max
}
constructor(min:String, max:String) {
this.min = Integer.parseInt(min)
this.max = Integer.parseInt(max)
}
override fun filter(source:CharSequence, start:Int, end:Int, dest: Spanned, dstart:Int, dend:Int): CharSequence? {
try
{
val input = Integer.parseInt(dest.toString() + source.toString())
if (isInRange(min, max, input))
return null
}
catch (nfe:NumberFormatException) {}
return ""
}
private fun isInRange(a:Int, b:Int, c:Int):Boolean {
return if (b > a) c in a..b else c in b..a
}
}
Then use this from your Kotlin class
percentage_edit_text.filters = arrayOf(Utilities.InputFilterMinMax(1, 100))
This EditText allows from 1 to 100.
Then use this from your XML
android:inputType="number"
please check this code
String pass = EditText.getText().toString();
if(TextUtils.isEmpty(pass) || pass.length < [YOUR MIN LENGTH])
{
EditText.setError("You must have x characters in your txt");
return;
}
//continue processing
edittext.setOnFocusChangeListener( new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
// USE your code here
}
USe the below link for more details about edittext and the edittextfilteres with text watcher..
http://www.mobisoftinfotech.com/blog/android/android-edittext-setfilters-example-numeric-text-field-patterns-and-length-restriction/
I found my own answer. It is very late now but I want to share it with you. I implement this interface:
import android.text.TextWatcher;
public abstract class MinMaxTextWatcher implements TextWatcher {
int min, max;
public MinMaxTextWatcher(int min, int max) {
super();
this.min = min;
this.max = max;
}
}
And then implement it in this way inside your activity:
private void limitEditText(final EditText ed, int min, int max) {
ed.addTextChangedListener(new MinMaxTextWatcher(min, max) {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String str = s.toString();
int n = 0;
try {
n = Integer.parseInt(str);
if(n < min) {
ed.setText(min);
Toast.makeText(getApplicationContext(), "Minimum allowed is " + min, Toast.LENGTH_SHORT).show();
}
else if(n > max) {
ed.setText("" + max);
Toast.makeText(getApplicationContext(), "Maximum allowed is " + max, Toast.LENGTH_SHORT).show();
}
}
catch(NumberFormatException nfe) {
ed.setText("" + min);
Toast.makeText(getApplicationContext(), "Bad format for number!" + max, Toast.LENGTH_SHORT).show();
}
}
});
}
This is a very simple answer, if any better please tell me.
Extension of Pratik's and Zac's answer. Zac fixed a small bug of Pratik's in his answer. But I notcied that code doesn't support negative values, it will throw a NumberFormatException. To fix that, and allow the MIN to be negative, use the following code.
Add this line (In bold) between the other two lines:
newVal = newVal.substring(0, dstart) + source.toString()+ newVal.substring(dstart, newVal.length());
if(newVal.equalsIgnoreCase("-") && min < 0)return null;
int input = Integer.parseInt(newVal);
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
// Remove the string out of destination that is to be replaced
String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
// Add the new string in
newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
//****Add this line (below) to allow Negative values***//
if(newVal.equalsIgnoreCase("-") && min < 0)return null;
int input = Integer.parseInt(newVal);
if (isInRange(min, max, input))
return null;
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
return "";
}