Home » Android » android – Currency input with 2 decimal format

android – Currency input with 2 decimal format

Posted by: admin May 14, 2020 Leave a comment

Questions:

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

    }


    }
}
How to&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, "#,

Answer:

"));

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("#,

Answer:

.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

Answer:

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.

Answer:

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("#,

Answer:

,##0.00"); return df.format(Double.valueOf(value)); }

Answer:

I lost incredible ten hours searching or trying codes for this.
So I gave up and built this code for myself. Its not revised yet but it works and I´ve came here to help others that went crazy with this like me.

The code basically is a function that will place a textWatcher and adjust the coma to the right place.
This code is for Kotlin.

First, create this function:

fun CurrencyWatcher( editText:EditText) {

    editText.addTextChangedListener(object : TextWatcher {
        //this will prevent the loop
        var changed: Boolean = false

        override fun afterTextChanged(p0: Editable?) {
            changed = false

        }

        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

            editText.setSelection(p0.toString().length)
        }

        @SuppressLint("SetTextI18n")
        override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            if (!changed) {
                changed = true

                var str: String = p0.toString().replace(",", "").trim()
                var element0: String = str.elementAt(0).toString()
                var element1: String = "x"
                var element2: String = "x"
                var element3: String = "x"
                var element4: String = "x"
                var element5: String = "x"
                var element6: String = "x"

                //this variables will store each elements of the initials data for the case we need to move this numbers like: 0,01 to 0,11 or 0,11 to 0,01
                if (str.length >= 2) {
                    element1 = str.elementAt(1).toString()
                }
                if (str.length >= 3) {
                    element2 = str.elementAt(2).toString()
                }

                editText.removeTextChangedListener(this)


                //this first block of code will take care of the case
                //where the number starts with 0 and needs to adjusta the 0 and the "," place
                if (str.length == 1) {
                    str = "0,0" + str
                    editText.setText(str)

                } else if (str.length <= 3 && str == "00") {

                    str = "0,00"
                    editText.setText(str)
                    editText.setSelection(str.length)
                } else if (element0 == "0" && element1 == "0" && element2 == "0") {
                    str = str.replace("000", "")
                    str = "0,0" + str
                    editText.setText(str)
                } else if (element0 == "0" && element1 == "0" && element2 != "0") {
                    str = str.replace("00", "")
                    str = "0," + str
                    editText.setText(str)
                } else {

                    //This block of code works with the cases that we need to move the "," only because the value is bigger
                    //lets get the others elements
                    if (str.length >= 4) {
                        element3 = str.elementAt(3).toString()
                    }
                    if (str.length >= 5) {
                        element4 = str.elementAt(4).toString()
                    }
                    if (str.length >= 6) {
                        element5 = str.elementAt(5).toString()
                    }
                    if (str.length == 7) {
                        element6 = str.elementAt(6).toString()
                    }


                    if (str.length >= 4 && element0 != "0") {

                        val sb: StringBuilder = StringBuilder(str)
                        //set the coma in right place
                        sb.insert(str.length - 2, ",")
                        str = sb.toString()
                    }

                    //change the 0,11 to 1,11
                    if (str.length == 4 && element0 == "0") {

                        val sb: StringBuilder = StringBuilder(str)
                        //takes the initial 0 out
                        sb.deleteCharAt(0);
                        str = sb.toString()

                        val sb2: StringBuilder = StringBuilder(str)
                        sb2.insert(str.length - 2, ",")
                        str = sb2.toString()
                    }

                    //this will came up when its like 11,11 and the user delete one, so it will be now 1,11
                    if (str.length == 3 && element0 != "0") {
                        val sb: StringBuilder = StringBuilder(str)
                        sb.insert(str.length - 2, ",")
                        str = sb.toString()
                    }

                    //came up when its like 0,11 and the user delete one, output will be 0,01
                    if (str.length == 2 && element0 == "0") {
                        val sb: StringBuilder = StringBuilder(str)
                        //takes 0 out
                        sb.deleteCharAt(0);
                        str = sb.toString()

                        str = "0,0" + str

                    }

                    //came up when its 1,11 and the user delete, output will be 0,11
                    if (str.length == 2 && element0 != "0") {
                        val sb: StringBuilder = StringBuilder(str)
                        //retira o 0 da frente
                        sb.insert(0, "0,")
                        str = sb.toString()

                    }


                    editText.setText(str)
                }

                //places the selector at the end to increment the number
                editText.setSelection(str.length)
                editText.addTextChangedListener(this)
            }

        }
    })
}

And then you call this function this way

val etVal:EditText = findViewById(R.id.etValue)

CurrencyWatcher(etVal)