Is there a way to define a min and max value for E

2019-01-01 03:54发布

问题:

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 can do it by using TextWatcher but I want to know if there is any other way to do it in layout file or elsewhere.

Edit: I don\'t want to limit character count. I want to limit the value. For example, if I limit month EditText w characters when I enter 12 it will accept it but if I enter 22 it mustn\'t accept it while I am entering.

回答1:

First make this class :

package com.test;

import android.text.InputFilter;
import android.text.Spanned;

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 use this from your Activity :

EditText et = (EditText) findViewById(R.id.myEditText);
et.setFilters(new InputFilter[]{ new InputFilterMinMax(\"1\", \"12\")});

This will allow user to enter values from 1 to 12 only.

EDIT :

Set your edittext with android:inputType=\"number\".

Thanks.



回答2:

There is a small error in Pratik\'s code. For instance, if a value is 10 and you add a 1 at the beginning to make 110, the filter function would treat the new value as 101.

See below for a fix to this:

@Override
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());
        int input = Integer.parseInt(newVal);
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) { }
    return \"\";
}


回答3:

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 \"\";
}


回答4:

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\')});


回答5:

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;
}


回答6:

If you need range with negative numbers like -90:90, you can use this solution.

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 {
        String stringInput = dest.toString() + source.toString();
        int value;
        if (stringInput.length() == 1 && stringInput.charAt(0) == \'-\') {
            value = -1;
        } else {
            value = Integer.parseInt(stringInput);
        }
        if (isInRange(min, max, value))
            return null;
    } catch (NumberFormatException nfe) {
    }
    return \"\";
}

private boolean isInRange(int min, int max, int value) {
    return max > min ? value >= min && value <= max : value >= max && value <= min;
}
}


回答7:

There is something wrong in the accepted answer.

int input = Integer.parseInt(dest.toString() + source.toString());

If I move cursor into middle of text, then type something, then the above statement will produce wrong result. For example, type \"12\" first, then type \"0\" between 1 and 2, then the statement mentioned above will produce \"120\" instead of 102. I modified this statement to statements below:

String destString = dest.toString();
  String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);
  int input = Integer.parseInt(inputString);


回答8:

I made a simpler way to set a min/max to an Edittext. I use arithmetic keypad and I work with this method:

 private int limit(EditText x,int z,int limin,int limax){

    if( x.getText().toString()==null || x.getText().toString().length()==0){
        x.setText(Integer.toString(limin));
        return z=0;
    }
    else{
        z = Integer.parseInt(x.getText().toString());
         if(z <limin || z>limax){
             if(z<10){
                 x.setText(Integer.toString(limin));
                return  z=0;
             }
            else{
                x.setText(Integer.toString(limax));
                return z=limax;
            }

         }
         else
            return z = Integer.parseInt(x.getText().toString());
    }
 }

The method accepts all of your values but if a value of users in not adhere to your limits it will be set automatically to the min/max limit. For ex. limit limin=10, limax =80 if the user sets 8, automatically 10 is saved to a variable and EditText is set to 10.



回答9:

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/



回答10:

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.



回答11:

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        String prefix = dest.toString().substring(0, dstart);
        String insert = source.toString();
        String suffix = dest.toString().substring(dend);
        String input_string = prefix + insert + suffix;
        int input = Integer.parseInt(input_string);

        if (isInRange(min, max, input) || input_string.length() < String.valueOf(min).length())
            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;
}


回答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\");
                    }......


回答13:

@Pratik Sharma

For support negative numbers, add the following code within the filter method:

package ir.aboy.electronicarsenal;

import android.text.InputFilter;
import android.text.Spanned;

public class InputFilterMinMax implements InputFilter {

  private int min, max;
  int input;

  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 {

      if ((dest.toString() + source.toString()).equals(\"-\")) {
        source = \"-1\";
      }

      input = Integer.parseInt(dest.toString() + source.toString());
      if (isInRange(min, max, input))
        return null;

    } catch (NumberFormatException ignored) {
    }
    return \"\";
  }

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

}

Then use this from your Activity :

findViewById(R.id.myEditText).setFilters(new InputFilter[]{ new InputFilterMinMax(1, 12)});

Set your edittext with:

android:inputType=\"number|numberSigned\"


回答14:

//still has some problem but Here you can use min, max at any range (positive or negative)

// in filter calss
 @Override
 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
            int input;
            String newVal = dest.toString() + source.toString();
            if (newVal.length() == 1 && newVal.charAt(0) == \'-\') {
                input = min; //allow
            }
            else {
                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());
                input = Integer.parseInt(newVal);
            }

            //int input = Integer.parseInt(dest.toString() + source.toString());

            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) {
        }
        return \"\";
    }

//also the filler must set as below: in the edit createview
// to allow enter number and backspace.
et.setFilters(new InputFilter[]{new InputFilterMinMax(min >= 10 ?  \"0\" : String.valueOf(min), max >-10 ? String.valueOf(max) :\"0\" )});



//and at same time must check range in the TextWatcher()
et.addTextChangedListener(new
 TextWatcher() {

      @Override
      public void afterTextChanged (Editable editable)
      {
         String tmpstr = et.getText().toString();
         if (!tmpstr.isEmpty() && !tmpstr.equals(\"-\") ) {
             int datavalue = Integer.parseInt(tmpstr);
             if ( datavalue >= min || datavalue <= max) {
               // accept data ...     
             }
         }
      }
 });


回答15:

To add to Pratik\'s answer, here is a modified version where user can enter min 2 digits also , for example, 15 to 100:

 import android.text.InputFilter;
 import android.text.Spanned;

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 {
            if(end==1)
                min=Integer.parseInt(source.toString());
            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;
    }}

added: if(end==1) min=Integer.parseInt(source.toString());

Hope this helps. kindly dont downvote without reasons.



回答16:

I know there are a million answers to this already, with one accepted. However, there are numerous bugs in the accepted answer and most of the rest simply fix one (or maybe two) of them, without expanding to all possible use cases.

So I basically compiled most of the bug fixes suggested in support answers as well as adding a method to allow continuous input of numbers outside of the range in the direction of 0 (if the range doesn\'t start at 0), at least until it\'s certain that it can no longer be in the range. Because to be clear, this is the only time that really causes trouble with many of the other solutions.

Here\'s the fix:

public class InputFilterIntRange implements InputFilter, View.OnFocusChangeListener {

    private final int min, max;

    public InputFilterIntRange(int min, int max) {
        if (min > max) {
            // Input sanitation for the filter itself
            int mid = max;
            max = min;
            min = mid;
        }
        this.min = min;
        this.max = max;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        // Determine the final string that will result from the attempted input
        String destString = dest.toString();
        String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);

        // Don\'t prevent - sign from being entered first if min is negative
        if (inputString.equalsIgnoreCase(\"-\") && min < 0) return null;

        try {
            int input = Integer.parseInt(inputString);
            if (mightBeInRange(input))
                return null;
        } catch (NumberFormatException nfe) {}

        return \"\";
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {

        // Since we can\'t actively filter all values
        // (ex: range 25 -> 350, input \"15\" - could be working on typing \"150\"),
        // lock values to range after text loses focus
        if (!hasFocus) {
            if (v instanceof EditText) sanitizeValues((EditText) v);
        }
    }

    private boolean mightBeInRange(int value) {
        // Quick \"fail\"
        if (value >= 0 && value > max) return false;
        if (value >= 0 && value >= min) return true;
        if (value < 0 && value < min) return false;
        if (value < 0 && value <= max) return true;

        boolean negativeInput = value < 0;

        // If min and max have the same number of digits, we can actively filter
        if (numberOfDigits(min) == numberOfDigits(max)) {
            if (!negativeInput) {
                if (numberOfDigits(value) >= numberOfDigits(min) && value < min) return false;
            } else {
                if (numberOfDigits(value) >= numberOfDigits(max) && value > max) return false;
            }
        }

        return true;
    }

    private int numberOfDigits(int n) {
        return String.valueOf(n).replace(\"-\", \"\").length();
    }

    private void sanitizeValues(EditText valueText) {
        try {
            int value = Integer.parseInt(valueText.getText().toString());
            // If value is outside the range, bring it up/down to the endpoint
            if (value < min) {
                value = min;
                valueText.setText(String.valueOf(value));
            } else if (value > max) {
                value = max;
                valueText.setText(String.valueOf(value));
            }
        } catch (NumberFormatException nfe) {
            valueText.setText(\"\");
        }
    }

}

Note that some input cases are impossible to handle \"actively\" (i.e., as the user is inputting it), so we must ignore them and handle them after the user is done editing the text.

Here\'s how you might use it:

EditText myEditText = findViewById(R.id.my_edit_text);
InputFilterIntRange rangeFilter = new InputFilterIntRange(25, 350);
myEditText.setFilters(new InputFilter[]{rangeFilter});

// Following line is only necessary if your range is like [25, 350] or [-350, -25].
// If your range has 0 as an endpoint or allows some negative AND positive numbers, 
// all cases will be handled pre-emptively.
myEditText.setOnFocusChangeListener(rangeFilter);

Now, when the user tries to type in a number closer to 0 than the range allows, one of two things will happen:

  1. If min and max have the same number of digits, they won\'t be allowed to input it at all once they get to the final digit.

  2. If a number outside of the range is left in the field when the text loses focus, it will automatically be adjusted to the closest boundary.

And of course, the user will never be allowed to input a value farther from 0 than the range allows, nor is it possible for a number like that to \"accidentally\" be in the text field for this reason.

Known Issue(s?)

  1. This only works if the EditText loses focus when the user is done with it.

The other option is sanitizing when the user hits the \"done\"/return key, but in many or even most cases, this causes a loss of focus anyways.

However, closing the soft keyboard will not automatically un-focus the element. I\'m sure 99.99% of Android developers wish it would (and that focus handling on EditText elements was less of a quagmire in general), but as of yet there is no built-in functionality for it. The easiest method that I\'ve found to get around this, if you need to, is to extend EditText something like this:

public class EditTextCloseEvent extends AppCompatEditText {

    public EditTextCloseEvent(Context context) {
        super(context);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            for (InputFilter filter : this.getFilters()) {
                if (filter instanceof InputFilterIntRange)
                    ((InputFilterIntRange) filter).onFocusChange(this, false);
            }
        }
        return super.dispatchKeyEvent(event);
    }
}

This will \"trick\" the filter into sanitizing the input even though the view hasn\'t actually lost focus. If the view happens to later lose focus on its own, the input sanitation will trigger again, but nothing will change since it was already fixed.

Closing

Whew. That was a lot. What originally seemed like it would be a pretty trivially easy problem ended up uncovering many little ugly pieces of vanilla Android (at least in Java). And once again, you only need to add the listener and extend EditText if your range does not include 0 in some way. (And realistically, if your range doesn\'t include 0 but starts at 1 or -1, you also won\'t run into problems.)

As a last note, this only works for ints. There is certainly a way to implement it to work with decimals (double, float), but since neither I nor the original asker have a need for that, I don\'t particularly want to get all that deep into it. It would be very easy to simply use the post-completion filtering along with the following lines:

// Quick \"fail\"
if (value >= 0 && value > max) return false;
if (value >= 0 && value >= min) return true;
if (value < 0 && value < min) return false;
if (value < 0 && value <= max) return true;

You would only have to change from int to float (or double), allow insertion of a single . (or ,, depending upon country?), and parse as one of the decimal types instead of an int.

That handles most of the work anyways, so it would work very similarly.



回答17:

here\'s the way I\'ve used, it\'s working for negative number

First, create MinMaxFIlter.java class with the following code :

import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;

/**
* Created by 21 on 4/5/2016.
*/
public class MinMaxFilter implements InputFilter {

private double mIntMin, mIntMax;

public MinMaxFilter(double minValue, double maxValue) {
    this.mIntMin = minValue;
    this.mIntMax = maxValue;
}

public MinMaxFilter(String minValue, String maxValue) {
    this.mIntMin = Double.parseDouble(minValue);
    this.mIntMax = Double.parseDouble(maxValue);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        Boolean isNeg = false;
        String provi = dest.toString() + source.toString();
        if(\"-\".equals(provi.substring(0,1))){
            if(provi.length()>1) {
                provi = provi.substring(1, provi.length());
                isNeg = true;
            }
            else{
                if(\"\".equals(source)){
                    return null;
                }
                return \"-\";
            }
        }

        double input = Double.parseDouble(provi); 
        if(isNeg){input = input * (-1);}

        if (isInRange(mIntMin, mIntMax, input)) {
            return null;
        }
    } catch (Exception nfe) {}
    return \"\";
}

private boolean isInRange(double a, double b, double c) {
    if((c>=a && c<=b)){
        return true;
    }
    else{
        return false;
    }
}
}

Then, create and set your filter to your edittext like this :

EditText edittext = new EditText(context);
editext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
eInt.setFilters(new InputFilter[]{new MinMaxFilter(min, max)});


回答18:

this is my code max=100, min=0

xml

<TextView
                    android:id=\"@+id/txt_Mass_smallWork\"
                    android:layout_width=\"match_parent\"
                    android:layout_height=\"wrap_content\"
                    android:textColor=\"#000\"
                    android:textSize=\"20sp\"
                    android:textStyle=\"bold\" />

java

EditText ed = findViewById(R.id.txt_Mass_smallWork);
    ed.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {`

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            if(!charSequence.equals(\"\")) {
                int massValue = Integer.parseInt(charSequence.toString());
                if (massValue > 10) {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(2)});
                } else {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(3)});
                }
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });


回答19:

Very simple example on Kotlin:

import android.text.InputFilter
import android.text.Spanned

class InputFilterRange(private var range: IntRange) : InputFilter {

    override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int) = try {
        val input = Integer.parseInt(dest.toString() + source.toString())
        if (range.contains(input)) null else \"\"
    } catch (nfe: NumberFormatException) {
        \"\"
    }
}