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

后端 未结 13 2047
花落未央
花落未央 2020-11-27 05:21

Im creating a convertor application, I want to set the EditText so that when the user is inputting the number to be converted, a thousand separator (,) should be added autom

13条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-27 05:34

    I know i am very late to the party but it may be very useful for future users. My answer is an extension of Shree Krishna's answer.

    Improvements:

    1. Thousands separators and Decimal markers are locale aware i.e. they are used accordingly to the Locale of the device.
    2. The cursor position doesn't change after deleting or adding elements in the middle also (In his answer cursor was reset to the end).
    3. The overall quality of the code has been improved specially the getDecimalFormattedString method.

    Code:

        import android.text.Editable;
        import android.text.TextWatcher;
        import android.widget.EditText;
    
        import java.text.DecimalFormat;
    
    
        /**
         * Created by srv_twry on 4/12/17.
         * Source: https://stackoverflow.com/a/34265406/137744
         * The custom TextWatcher that automatically adds thousand separators in EditText.
         */
    
        public class ThousandSeparatorTextWatcher implements TextWatcher {
    
            private DecimalFormat df;
            private EditText editText;
            private static String thousandSeparator;
            private static String decimalMarker;
            private int cursorPosition;
    
            public ThousandSeparatorTextWatcher(EditText editText) {
                this.editText = editText;
                df = new DecimalFormat("#,###.##");
                df.setDecimalSeparatorAlwaysShown(true);
                thousandSeparator = Character.toString(df.getDecimalFormatSymbols().getGroupingSeparator());
                decimalMarker = Character.toString(df.getDecimalFormatSymbols().getDecimalSeparator());
            }
    
            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
                cursorPosition = editText.getText().toString().length() - editText.getSelectionStart();
            }
    
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    
            @Override
            public void afterTextChanged(Editable s) {
                try {
                    editText.removeTextChangedListener(this);
                    String value = editText.getText().toString();
    
                    if (value != null && !value.equals("")) {
                        if (value.startsWith(decimalMarker)) {
                            String text = "0" + decimalMarker;
                            editText.setText(text);
                        }
                        if (value.startsWith("0") && !value.startsWith("0" + decimalMarker)) {
                            int index = 0;
                            while (index < value.length() && value.charAt(index) == '0') {
                                index++;
                            }
                            String newValue = Character.toString(value.charAt(0));
                            if (index != 0) {
                                newValue = value.charAt(0) + value.substring(index);
                            }
                            editText.setText(newValue);
                        }
                        String str = editText.getText().toString().replaceAll(thousandSeparator, "");
                        if (!value.equals("")) {
                            editText.setText(getDecimalFormattedString(str));
                        }
                        editText.setSelection(editText.getText().toString().length());
                    }
    
                    //setting the cursor back to where it was
                    editText.setSelection(editText.getText().toString().length() - cursorPosition);
                    editText.addTextChangedListener(this);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    editText.addTextChangedListener(this);
                }
            }
    
            private static String getDecimalFormattedString(String value) {
    
                String[] splitValue = value.split("\\.");
                String beforeDecimal = value;
                String afterDecimal = null;
                String finalResult = "";
    
                if (splitValue.length == 2) {
                    beforeDecimal = splitValue[0];
                    afterDecimal = splitValue[1];
                }
    
                int count = 0;
                for (int i = beforeDecimal.length() - 1; i >= 0 ; i--) {
                    finalResult = beforeDecimal.charAt(i) + finalResult;
                    count++;
                    if (count == 3 && i > 0) {
                        finalResult = thousandSeparator + finalResult;
                        count = 0;
                    }
                }
    
                if (afterDecimal != null) {
                    finalResult = finalResult + decimalMarker + afterDecimal;
                }
    
                return finalResult;
            }
    
            /*
            * Returns the string after removing all the thousands separators.
            * */
            public static String getOriginalString(String string) {
                return string.replace(thousandSeparator,"");
            }
        }
    

提交回复
热议问题