2015-09-14 1 views
1

Je suis novice dans Android et je veux faire un masque pour un EditText avec un nombre décimal avec 3 décimales (ex: 0.658), j'ai besoin d'un masque cet utilisateur n'a pas besoin d'écrire le ".", seulement les chiffres, comme un masque conventionnel pour la monnaie.EditText masque avec 3 décimales dans java [android]

Je suis en train de créer un TextWatcher basé à ceci:

public static TextWatcher currency(final EditText editText) { 
    return new TextWatcher() { 
     String current = ""; 

     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      if (!s.toString().equals(current)) { 
       editText.removeTextChangedListener(this); 

       String cleanString = s.toString(); 

       if(count != 0) { 
        String substr = cleanString.substring(cleanString.length() - 2); 

        if (substr.contains(".") || substr.contains(",")) { 
         cleanString += "0"; 
        } 
       } 

       cleanString = cleanString.replaceAll("[R$,.]", ""); 

       double parsed = Double.parseDouble(cleanString); 
       Locale locale = new Locale("pt", "BR"); 
       String formatted = NumberFormat.getCurrencyInstance(locale).format((parsed/100)); 
       formatted = formatted.replaceAll("[R$]", ""); 

       current = formatted; 
       editText.setText(formatted); 
       editText.setSelection(formatted.length()); 

       editText.addTextChangedListener(this); 
      } 
     } 

     public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 

     public void afterTextChanged(Editable s) {} 
    }; 
} 

Mais sans succès.

Il existe une meilleure façon de faire cela?

Merci.

Répondre

0

J'ai eu un problème similaire. J'ai donc commencé à chercher toute implémentation de TextWatcher. J'ai finalement décidé de construire mon propre:

public class BrRealMoneyTextWatcher implements TextWatcher { 

    private static final Locale DEFAULT_LOCALE = new Locale("pt", "BR"); 

    private static DecimalFormat NUMBER_FORMAT = (DecimalFormat) DecimalFormat.getCurrencyInstance(DEFAULT_LOCALE); 

    private static final int FRACTION_DIGITS = 2; 

    private static final String DECIMAL_SEPARATOR; 

    private static final String CURRENCY_SIMBOL; 

    static { 
     NUMBER_FORMAT.setMaximumFractionDigits(FRACTION_DIGITS); 
     NUMBER_FORMAT.setMaximumFractionDigits(FRACTION_DIGITS); 
     NUMBER_FORMAT.setParseBigDecimal(true); 
     DECIMAL_SEPARATOR = String.valueOf(NUMBER_FORMAT.getDecimalFormatSymbols().getDecimalSeparator()); 
     CURRENCY_SIMBOL = NUMBER_FORMAT.getCurrency().getSymbol(DEFAULT_LOCALE); 
    } 

    final EditText target; 

    public BrRealMoneyTextWatcher(EditText target) { 
     this.target = target; 
    } 

    private boolean updating = false; 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int after) { 
     if (updating) { 
      updating = false; 
      return; 
     } 

     updating = true; 
     try { 
      String valueStr = formatNumber(fixDecimal(s.toString())); 
      BigDecimal parsedValue = ((BigDecimal) NUMBER_FORMAT.parse(valueStr)); 
      String value = NUMBER_FORMAT.format(parsedValue); 
      target.setText(value); 
      target.setSelection(value.length()); 
     } catch (ParseException | NumberFormatException ex) { 
      throw new IllegalArgumentException("Erro ao aplicar a máscara", ex); 
     } 
    } 

    private String formatNumber(String originalNumber) { 
     String number = originalNumber.replaceAll("[^\\d]", ""); 
     switch(number.length()) { 
      case 0 : 
       number = "0" + DECIMAL_SEPARATOR + "00"; 
       break; 
      case 1 : 
       number = "0" + DECIMAL_SEPARATOR + "0" + number; 
       break; 
      case 2 : 
       number = "0" + DECIMAL_SEPARATOR + number; 
       break; 
      default: 
       number = number.substring(0, number.length() - 2) + DECIMAL_SEPARATOR + number.substring(number.length() - 2); 
       break; 
     } 
     return CURRENCY_SIMBOL + number; 
    } 

    private String fixDecimal(String number) { 
     int dotPos = number.indexOf('.') + 1; 
     int length = number.length(); 
     return (length - dotPos < FRACTION_DIGITS) ? fixDecimal(number + "0") : number; 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
    } 
} 

J'espère que ça aide quelqu'un d'autre.