Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Currency input with 2 decimal format

I need to format input currency with 2 decimal format example when user enter 2 it looks $2.00 then when when user enter 2 it convert to $22.00 ... etc

I approach to something similar , when user enter 2 it convert to $0.02 next 2 will be like this $0.22

any one can help me thank you

public class MoneyTextWatcher implements TextWatcher {
    private final WeakReference<EditText> editTextWeakReference;

    public MoneyTextWatcher(EditText mEditText) {
        editTextWeakReference = new WeakReference<EditText>(mEditText);
    }

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

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

       EditText editTex = editTextWeakReference.get();
        if(!s.toString().equals(editTex.getText())) {
            editTex.removeTextChangedListener(this);
            String cleanString = s.toString().replaceAll("[$,.]", "");
            double parsed = Double.parseDouble(cleanString.replaceAll("[^\\d]", ""));
            String formatted = NumberFormat.getCurrencyInstance().format((parsed / 100));
            editTex.setText(formatted);
            editTex.setSelection(formatted.length());

            editTex.addTextChangedListener(this);

    }

    @Override
    public void afterTextChanged(Editable s) {

    }


    }
}
like image 475
Mina Fawzy Avatar asked Oct 24 '15 15:10

Mina Fawzy


3 Answers

I think you can try the following:

Layout:

<EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="numberDecimal"
        />

Activity:

EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new NumberTextWatcher(editText, "#,###"));

with text watcher as the following:

public class NumberTextWatcher implements TextWatcher {

    private final DecimalFormat df;
    private final DecimalFormat dfnd;
    private final EditText et;
    private boolean hasFractionalPart;
    private int trailingZeroCount;

    public NumberTextWatcher(EditText editText, String pattern) {
        df = new DecimalFormat(pattern);
        df.setDecimalSeparatorAlwaysShown(true);
        dfnd = new DecimalFormat("#,###.00");
        this.et = editText;
        hasFractionalPart = false;
    }

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

        if (s != null && !s.toString().isEmpty()) {
            try {
                int inilen, endlen;
                inilen = et.getText().length();
                String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "").replace("$","");
                Number n = df.parse(v);
                int cp = et.getSelectionStart();
                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));
                }
                et.setText("$".concat(et.getText().toString()));
                endlen = et.getText().length();
                int sel = (cp + (endlen - inilen));
                if (sel > 0 && sel < et.getText().length()) {
                    et.setSelection(sel);
                } else if (trailingZeroCount > -1) {
                    et.setSelection(et.getText().length() - 3);
                } else {
                    et.setSelection(et.getText().length());
                }
            } catch (NumberFormatException | ParseException e) {
                e.printStackTrace();
            }
        }

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

enter image description here

like image 131
BNK Avatar answered Oct 17 '22 21:10

BNK


Keep the number entered by the user stored apart, since if you use your edittext.text you will have more problems.

Then use DecimalFormat to format it like you need.

For the first, maybe its a good way to restore the original input to the edittext as soon as the users begins editing, this way you can avoid problems with the editing.

Hope this helps.

like image 44
Nanoc Avatar answered Oct 17 '22 23:10

Nanoc


HI below code will convert every number to two decimal. the value should be number, characters and special characters can cause numberformat exception. please handle that as you needed. Thanks

    public static String formatDecimal(String value) {
    DecimalFormat df = new DecimalFormat("#,###,##0.00");
    return df.format(Double.valueOf(value));
}
like image 1
Arun Antoney Avatar answered Oct 17 '22 22:10

Arun Antoney