Mascara does not show decimals with 0

2

I have this class that I use as a Number Mask

public class Mask implements TextWatcher {

    private DecimalFormat df;
    private DecimalFormat dfnd;
    private boolean hasFractionalPart;

    private EditText et;

    public Mask(EditText et)
    {
        df = new DecimalFormat("#,###.##");
        df.setDecimalSeparatorAlwaysShown(true);
        dfnd = new DecimalFormat("#,###");
        this.et = et;
        hasFractionalPart = false;
    }

    @SuppressWarnings("unused")
    private static final String TAG = "NumberTextWatcher";

    @Override
    public void afterTextChanged(Editable s)
    {
        et.removeTextChangedListener(this);

        try {
            int inilen, endlen;
            inilen = et.getText().length();

            String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
            Number n = df.parse(v);
            int cp = et.getSelectionStart();
            if (hasFractionalPart) {
                et.setText(df.format(n));
            } else {
                et.setText(dfnd.format(n));
            }
            endlen = et.getText().length();
            int sel = (cp + (endlen - inilen));
            if (sel > 0 && sel <= et.getText().length()) {
                et.setSelection(sel);
            } else {
                // place cursor at the end?
                et.setSelection(et.getText().length() - 1);
            }
        } catch (NumberFormatException nfe) {
            // do nothing?
        } catch (ParseException e) {
            // do nothing?
        }

        et.addTextChangedListener(this);
    }

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

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)
    {
        if (s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())))
        {
            hasFractionalPart = true;
        } else {
            hasFractionalPart = false;
        }
    }

}

My problem is that everything works correctly, Separate the thousands with the COMA ","

for example 5,300

Decimals are also good

for example 5.33

What does not work is that if I want to write 5.01, it does not let me put a 0 in front of me, nor does it work behind me, 5.10, just write me 5.1, I appreciate any help

    
asked by Bruno Sosa Fast Tag 14.09.2017 в 17:32
source

3 answers

3
  

If I want to write 5.01, it does not let me put a 0 in front, nor   also not behind, 5.10, just write me 5.1, I appreciate   any help

In this case it is not enough to change the format, in fact the modification of the value is being done within afterTextChanged() since a fraction with 0 is not valid, what has to be done is to store the final zeros and add when the format is applied.

You can see a solution made by SAM in your answer:

You can not enter zero after the decimal point in Android EditText

What you do is precisely store in a StringBuilder the "leading zeros" in the case of writing a zero after the decimal point, based on that solution is applied to your class:

public class Mask implements TextWatcher {

    private DecimalFormat df;
    private DecimalFormat dfnd;
    private boolean hasFractionalPart;
    private int trailingZeroCount;

    private EditText et;

    public Mask(EditText et)
    {
        df = new DecimalFormat("#,###.##");
        df.setDecimalSeparatorAlwaysShown(true);
        dfnd = new DecimalFormat("#,###");
        this.et = et;
        hasFractionalPart = false;
    }

    @SuppressWarnings("unused")
    private static final String TAG = "NumberTextWatcher";

    @Override
    public void afterTextChanged(Editable s)
    {
        et.removeTextChangedListener(this);

        try {
            int inilen, endlen;
            inilen = et.getText().length();

            String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
            Number n = df.parse(v);
            int cp = et.getSelectionStart();
            /*if (hasFractionalPart) {
                et.setText(df.format(n));
            } else {
                et.setText(dfnd.format(n));
            }*/
            if (hasFractionalPart) {
                StringBuilder trailingZeros = new StringBuilder();
                while (trailingZeroCount-- > 0)
                    trailingZeros.append('0');
                et.setText(df.format(n) + trailingZeros.toString());
            } else {
                et.setText(dfnd.format(n));
            }

            endlen = et.getText().length();
            int sel = (cp + (endlen - inilen));
            if (sel > 0 && sel <= et.getText().length()) {
                et.setSelection(sel);
            } else {
               // place cursor at the end?
               et.setSelection(et.getText().length() -1 );
            }
        } catch (NumberFormatException nfe) {
            // do nothing?
        } catch (ParseException e) {
            // do nothing?
        }

        et.addTextChangedListener(this);
    }

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

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)
    {
        int index = s.toString().indexOf(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator()));
        trailingZeroCount = 0;
        if (index > -1)
        {
            for (index++; index < s.length(); index++) {
                if (s.charAt(index) == '0')
                    trailingZeroCount++;
                else {
                    trailingZeroCount = 0;
                }
            }

            hasFractionalPart = true;
        } else {
            hasFractionalPart = false;
        }
        /*if (s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())))
        {
            hasFractionalPart = true;
        } else {
            hasFractionalPart = false;
        }*/

    }

}

in this way you can write as examples:

5.01
5.10
5000.01
5000.10

I add an example of how to use the class of @BrunoSosaFastTag

 EditText edtext = (EditText)findViewById(R.id.et1);
 Mask mask = new Mask(edtext);
 edtext.addTextChangedListener(mask);
    
answered by 18.09.2017 / 20:52
source
0

What you are saying Elderly works correctly, with a small point:

df = new DecimalFormat("#,###0.000");

I should show you correctly.

    
answered by 18.09.2017 в 17:20
-1

It should work simply with the mask

DecimalFormat("#,###.00");
    
answered by 18.09.2017 в 17:25