Как ограничить длину EditText до 7 целых чисел и 2 десятичных знаков?

У меня есть окно EditText которое должно позволить пользователю вводить до 7 чисел и два десятичных знака. После ввода семи цифр он не должен позволять добавлять еще одну цифру, но я могу разрешить до двух знаков после запятой. Я использую десятичный фильтр для двух знаков после запятой, и этот код в XML

 android:maxLength="7" android:imeOptions="actionDone" android:inputType="numberDecimal" 

Но EditText позволяет enter 8 цифр. Как это можно решить?

Solutions Collecting From Web of "Как ограничить длину EditText до 7 целых чисел и 2 десятичных знаков?"

Попробуйте это в onCreate

  youreditText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,1)}); 

Это где угодно в вашей программе

  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; } } 
 edittext.setFilters(new InputFilter[] { new DigitsKeyListener( Boolean.FALSE, Boolean.TRUE) { int beforeDecimal = 7, afterDecimal = 2; @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { String etText = edittext.getText().toString(); if (etText.isEmpty()){ return null; } String temp = edittext.getText() + source.toString(); if (temp.equals(".")) { return "0."; } else if (temp.toString().indexOf(".") == -1) { // no decimal point placed yet if (temp.length() > beforeDecimal) { return ""; } } else { int dotPosition ; int cursorPositon = edittext.getSelectionStart(); if (etText.indexOf(".") == -1) { Log.i("First time Dot", etText.toString().indexOf(".")+" "+etText); dotPosition = temp.indexOf("."); Log.i("dot Positon", cursorPositon+""); Log.i("dot Positon", etText+""); Log.i("dot Positon", dotPosition+""); }else{ dotPosition = etText.indexOf("."); Log.i("dot Positon", cursorPositon+""); Log.i("dot Positon", etText+""); Log.i("dot Positon", dotPosition+""); } if(cursorPositon <= dotPosition){ Log.i("cursor position", "in left"); String beforeDot = etText.substring(0, dotPosition); if(beforeDot.length()<beforeDecimal){ return source; }else{ if(source.toString().equalsIgnoreCase(".")){ return source; }else{ return ""; } } }else{ Log.i("cursor position", "in right"); temp = temp.substring(temp.indexOf(".") + 1); if (temp.length() > afterDecimal) { return ""; } } } return super.filter(source, start, end, dest, dstart, dend); } } }); 
 public class DecimalDigitsInputFilter implements InputFilter { Pattern mPattern; int digitsBeforeZero; public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) { this.digitsBeforeZero = digitsBeforeZero; 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()) { if (dest.toString().contains(".")) { if (dest.toString().substring(dest.toString().indexOf(".")).length() > 2) { return ""; } return null; } else if (!Pattern.compile("[0-9]{0," + (digitsBeforeZero - 1) + "}").matcher(dest).matches()) { if (!dest.toString().contains(".")) { if (source.toString().equalsIgnoreCase(".")) { return null; } } return ""; } else { return null; } } return null; } } 

Хотя это не прямое решение, вы можете управлять каждым символом, который идет из IME в EditText через TextWatcher

Один из SO Q & A о том, как использовать TextWatcher , здесь

Подробнее о TextWatcher здесь

Возможно, вам понадобится помощь регулярного выражения для соответствия точности с плавающей запятой и шаблона для проверки ввода.

Вы можете использовать этот фильтр ввода для решения вашей проблемы. Чтобы установить фильтр:

 mEditText.setFilters(new InputFilter[]{new DigitsInputFilter(maxDigitsBeforeDot, maxDigitsAfterDot, maxValue)}); 

Если вы не хотите ограничивать цифры до или после точки, просто поместите Integer.MAX_VALUE , чтобы отключить максимальный предел значения, используйте Double.POSITIVE_INFINITY .

Вы можете использовать этот фильтр для текстовых полей, в которые вы вводите числа или цифры и текст.

 public class DigitsInputFilter implements InputFilter { private final String DOT = "."; private int mMaxIntegerDigitsLength; private int mMaxDigitsAfterLength; private double mMax; public DigitsInputFilter(int maxDigitsBeforeDot, int maxDigitsAfterDot, double maxValue) { mMaxIntegerDigitsLength = maxDigitsBeforeDot; mMaxDigitsAfterLength = maxDigitsAfterDot; mMax = maxValue; } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { String allText = getAllText(source, dest, dstart); String onlyDigitsText = getOnlyDigitsPart(allText); if (allText.isEmpty()) { return null; } else { double enteredValue; try { enteredValue = Double.parseDouble(onlyDigitsText); } catch (NumberFormatException e) { return ""; } return checkMaxValueRule(enteredValue, onlyDigitsText); } } private CharSequence checkMaxValueRule(double enteredValue, String onlyDigitsText) { if (enteredValue > mMax) { return ""; } else { return handleInputRules(onlyDigitsText); } } private CharSequence handleInputRules(String onlyDigitsText) { if (isDecimalDigit(onlyDigitsText)) { return checkRuleForDecimalDigits(onlyDigitsText); } else { return checkRuleForIntegerDigits(onlyDigitsText.length()); } } private boolean isDecimalDigit(String onlyDigitsText) { return onlyDigitsText.contains(DOT); } private CharSequence checkRuleForDecimalDigits(String onlyDigitsPart) { String afterDotPart = onlyDigitsPart.substring(onlyDigitsPart.indexOf(DOT), onlyDigitsPart.length() - 1); if (afterDotPart.length() > mMaxDigitsAfterLength) { return ""; } return null; } private CharSequence checkRuleForIntegerDigits(int allTextLength) { if (allTextLength > mMaxIntegerDigitsLength) { return ""; } return null; } private String getOnlyDigitsPart(String text) { return text.replaceAll("[^0-9?!\\.]", ""); } private String getAllText(CharSequence source, Spanned dest, int dstart) { String allText = ""; if (!dest.toString().isEmpty()) { if (source.toString().isEmpty()) { allText = deleteCharAtIndex(dest, dstart); } else { allText = new StringBuilder(dest).insert(dstart, source).toString(); } } return allText; } private String deleteCharAtIndex(Spanned dest, int dstart) { StringBuilder builder = new StringBuilder(dest); builder.deleteCharAt(dstart); return builder.toString(); } } 

Надеюсь, это поможет вам.