0

Can I ask how to format string value e.g. 5000000.00 to 5,000,000.00? Apparently I'm doing currency related stuff for android application, I can managed to just format string value 5000000 to 5,000,000 without the dot separator in the edit text. I would like to store the string value for later to be used to parseDouble so that I will need to calculate and have some decimals. I managed to do with just comma separator but any idea on how to make the dot to be shown in the edit text as well? The following is my code:

amountText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

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

            @Override
            public void afterTextChanged(Editable s) {
                amountText.removeTextChangedListener(this);
                if(!amountText.getText().toString().equals(""))
                {
                    try {
                        String editText = amountText.getText().toString();
                        String newStr = editText.replace("$", "").replace(",", "");
                        customer.getProperty().get(groupPosition).setAmount(newStr);
                        String formattedString = formatString(customer.getProperty().get(groupPosition).getAmount());
                        amountText.setText(formattedString);
                        amountText.setSelection(amountText.getText().length());
                        // to place the cursor at the end of text
                    } catch (NumberFormatException nfe) {
                        nfe.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                amountText.addTextChangedListener(this);
            }
        });

public String formatString(String s)
{
        String givenstring = s.toString();
        Long longval;
        if (givenstring.contains(",")) {
            givenstring = givenstring.replaceAll(",", "");
        }
        longval = Long.parseLong(givenstring);
        DecimalFormat formatter = new DecimalFormat("#,###,###");
        String formattedString = formatter.format(longval);
        return formattedString;
}

I have tested use parseDouble but when I input "." in EditText, it just won't appear, and if I used long variable instead, it will give wrong format and error. (java.lang.NumberFormatException: Invalid long: "500000.00"). All values are done in string and later processing I will just parse the value when doing calculation. Thank you and appreciate for anyone guidance and I apologize if there exists the post that is similar as I did not manage to find solution yet.

R. Zagórski
  • 20,020
  • 5
  • 65
  • 90
johnnyhill
  • 85
  • 1
  • 1
  • 7
  • I had tried with different pattern "###,###.###" for decimal format as well but no luck, it still does not work. – johnnyhill Feb 02 '17 at 07:21

2 Answers2

2

This is working & fully tested code just copy & paste it to try

TextWatcher amountTextWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

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

            @Override
            public void afterTextChanged(Editable s) {
                    int cursorPosition = etAmount.getSelectionEnd();
                    String originalStr = etAmount.getText().toString();

                    //To restrict only two digits after decimal place
                    etAmount.setFilters(new InputFilter[]{new MoneyValueFilter(Integer.parseInt(2))});

                try {
                        etAmount.removeTextChangedListener(this);
                        String value = etAmount.getText().toString();

                        if (value != null && !value.equals("")) {
                            if (value.startsWith(".")) {
                                etAmount.setText("0.");
                            }
                            if (value.startsWith("0") && !value.startsWith("0.")) {
                                etAmount.setText("");
                            }
                            String str = etAmount.getText().toString().replaceAll(",", "");
                            if (!value.equals(""))
                                etAmount.setText(getDecimalFormattedString(str));

                            int diff = etAmount.getText().toString().length() - originalStr.length();
                            etAmount.setSelection(cursorPosition + diff);
                        }
                        etAmount.addTextChangedListener(this);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        etAmount.addTextChangedListener(this);
                    }
                }
            }
        };
        etAmount.addTextChangedListener(amountTextWatcher);

Here is method to add comma seperator to decimal number

/**
     * Get decimal formated string to include comma seperator to decimal number
     *
     * @param value
     * @return
     */
    public static String getDecimalFormattedString(String value) {
        if (value != null && !value.equalsIgnoreCase("")) {
            StringTokenizer lst = new StringTokenizer(value, ".");
            String str1 = value;
            String str2 = "";
            if (lst.countTokens() > 1) {
                str1 = lst.nextToken();
                str2 = lst.nextToken();
            }
            String str3 = "";
            int i = 0;
            int j = -1 + str1.length();
            if (str1.charAt(-1 + str1.length()) == '.') {
                j--;
                str3 = ".";
            }
            for (int k = j; ; k--) {
                if (k < 0) {
                    if (str2.length() > 0)
                        str3 = str3 + "." + str2;
                    return str3;
                }
                if (i == 3) {
                    str3 = "," + str3;
                    i = 0;
                }
                str3 = str1.charAt(k) + str3;
                i++;
            }
        }
        return "";
    }

Method to restrict only two digits after decimal place in edittext

/**
     * Restrict digits after decimal point value as per currency
     */
    class MoneyValueFilter extends DigitsKeyListener {
        private int digits;

        public MoneyValueFilter(int i) {
            super(false, true);
            digits = i;
        }

        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            CharSequence out = super.filter(source, start, end, dest, dstart, dend);

            // if changed, replace the source
            if (out != null) {
                source = out;
                start = 0;
                end = out.length();
            }

            int len = end - start;

            // if deleting, source is empty
            // and deleting can't break anything
            if (len == 0) {
                return source;
            }

            int dlen = dest.length();

            // Find the position of the decimal .
            for (int i = 0; i < dstart; i++) {
                if (dest.charAt(i) == '.') {
                    // being here means, that a number has
                    // been inserted after the dot
                    // check if the amount of digits is right
                    return getDecimalFormattedString((dlen - (i + 1) + len > digits) ? "" : String.valueOf(new SpannableStringBuilder(source, start, end)));
                }
            }

            for (int i = start; i < end; ++i) {
                if (source.charAt(i) == '.') {
                    // being here means, dot has been inserted
                    // check if the amount of digits is right
                    if ((dlen - dend) + (end - (i + 1)) > digits)
                        return "";
                    else
                        break; // return new SpannableStringBuilder(source,
                    // start, end);
                }
            }

            // if the dot is after the inserted part,
            // nothing can break
            return getDecimalFormattedString(String.valueOf(new SpannableStringBuilder(source, start, end)));
        }
    }
Divyang Panchal
  • 1,889
  • 1
  • 19
  • 27
  • Hi, thanks for the post, may I know where is the cursorPosition and originalStr? – johnnyhill Feb 02 '17 at 08:47
  • Thanks, it works perfectly, I originally used editText.setSelection(amountText.getText().length()); instead of the cursor position and the originalStr, it will still bring to the end of the text. But using this does not limit the decimal places, any idea how to make it just 2 decimal after the "." input? – johnnyhill Feb 02 '17 at 08:56
  • Happy to hear that – Divyang Panchal Feb 02 '17 at 08:57
  • @johnnyhill I have updated my answer & added a method to restrict only two digits after decimal place, also added implementation in afterTextChanged with comment – Divyang Panchal Feb 02 '17 at 09:04
0

Try this:

public void afterTextChanged(Editable view) {
    String s = null;
    try {
        // The comma in the format specifier does the trick
        s = String.format("%,d", Long.parseLong(view.toString()));
    } catch (NumberFormatException e) {
    }
    // Set s back to the view after temporarily removing the text change listener
}

Source: How to Automatically add thousand separators as number is input in EditText

Community
  • 1
  • 1
Suhayl SH
  • 1,213
  • 1
  • 11
  • 16
  • Thanks for the reply, but I think this is not workable for me? Because I am typing the input in real time and need the format to be changed whenever I key in the inputs. For example, I key in 5, 50, 500, 5000 then when it reaches 5000 it will auto format to 5,000. And this code gives me error "java.lang.NumberFormatException: Invalid long: "com.example.daniel.test.CustomEditText{ffcf1c2 VFED..CL. .F...... 80,0-400,86 #7f0d00aa app:id/installmentET}"" – johnnyhill Feb 02 '17 at 07:32
  • It will, once you add a TextChangedListener to your edit text. http://stackoverflow.com/questions/5567373/clear-edittext-text-after-adding-ontextchanged-implemenation – Suhayl SH Feb 02 '17 at 07:35
  • This code works, but it does not work with the after dot "." part where after i input the ".", the value is not shown when I click other view n click again edit text, the "." after values missing due to the error java.lang.NumberFormatException: Invalid long: "50000000.00" – johnnyhill Feb 02 '17 at 07:52