2013-07-02 10 views
8

Mam pudełko EditText, które musi umożliwiać użytkownikowi wprowadzenie do 7 cyfr i dwóch miejsc dziesiętnych. Po wprowadzeniu siedmiu cyfr nie powinno to pozwolić na dodanie jeszcze jednej cyfry, ale mogę pozwolić na 2 miejsca dziesiętne. Używam filtru dziesiętną do 2 miejsc po przecinku i ten kod w XMLJak ograniczyć długość EditText do 7 liczb całkowitych i 2 miejsc po przecinku?

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

Ale EditText zezwala na enter 8 cyfr. Jak można to rozwiązać?

+0

spróbować z formatem ... –

Odpowiedz

4
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); 
      } 
     } }); 
18

Spróbuj pod onCreate

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

to nigdzie w programie

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

     } 
1
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; 
    } 
} 
+0

to nie będzie działać poprawnie, jeśli istnieje przecinek tysięcy Separator jest tam Załóżmy, że edittext jest sformatowany przy użyciu formatu liczbowego, używając angielskiego ustawienia narodowego, tam będzie przecinek dla każdej liczby> 999, a te liczby nie będą pasować do wzorca ur, dlatego przy zmianie liczby od 4500,00 do 5600 wyświetlanych będzie tylko 600. – KJEjava48

1

Można użytkownik ten filtr wejściowy, aby rozwiązać swój problem. Aby ustawić filtr:

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

Jeśli nie chcemy ograniczać cyfry przed lub po kropce prostu umieścić Integer.MAX_VALUE, aby wyłączyć limitu wartości max użytku Double.POSITIVE_INFINITY.

Możesz użyć tego filtra do pól tekstowych, w których wprowadzasz cyfry lub liczby oraz tekst.

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

Mam nadzieję, że ci to pomoże.

0

Możesz poprawić go przy użyciu Android wiązania z danymi tak:

Definiowanie niestandardowych wiążącej adaptera:

@BindingAdapter({"digitsBeforeZero", "digitsAfterZero"}) 
public void bindAmountInputFilter(EditText view, int digitsBeforeZero, int digitsAfterZero) { 
     view.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(digitsBeforeZero, digitsAfterZero)}); 
} 

dodać atrybuty do EditText:

app:digitsBeforeZero="@{7}" 
app:digitsAfterZero="@{2}" 

i automatycznie ustawić wejście filtr dla edittext

0

Możesz użyć tego wejścia fil ter, aby rozwiązać twój problem.Aby ustawić filtr „##### ##” Przez 4 cyfr i dwóch miejsc po przecinku

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) { 

     String s = Html.toHtml(dest).replaceAll("\\<.*?>","").replaceAll("\n",""); 
     Matcher matcher = mPattern.matcher(dest); 
     if (!matcher.matches()) 
      return ""; 
     try { 
      if(Double.parseDouble(s)<9999.99 && s.contains(".")) { 
       return null; 
      }else if ((Double.parseDouble(s)<1000 && !s.contains("."))||source.equals(".")) { 
       return null; 
      }else { 
       return ""; 
      } 
     }catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

} 

    editText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(7, 2)}); 
Powiązane problemy