如何在EditText中输入自动添加千位分隔符作为数字

Asi*_*mwe 48 android android-emulator android-layout android-edittext

我创建一个转换器应用程序,我想设置EditText,以便当用户输入要转换的数字时,一旦它增加3个数字,就应该实时自动添加一千个分隔符(,)....千万,百万,十亿等,当删除到4以下数字时,这个数字会恢复正常.有帮助吗?谢谢.

Shr*_*hna 44

最后解决了这个问题

虽然答案太晚了.我已经研究了很多来完成任务以获得正确的结果,但却无法完成.所以我终于解决了我们正在搜索的问题,并向谷歌搜索者提供了这个答案,以节省他们的搜索时间.

以下代码的详细说明

  1. EditText随着文本的变化,将千位分隔符放入其中.

  2. 0.在按下句点(.)时自动添加.

  3. 忽略0Beginning处的输入.

只需复制以下命名的类

NumberTextWatcherForThousand实现 TextWatcher

import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import java.util.StringTokenizer;

/**
 * Created by skb on 12/14/2015.
 */
public class NumberTextWatcherForThousand implements TextWatcher {

    EditText editText;


    public NumberTextWatcherForThousand(EditText editText) {
        this.editText = editText;


    }

    @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) {
        try
        {
            editText.removeTextChangedListener(this);
            String value = editText.getText().toString();


            if (value != null && !value.equals(""))
            {

                if(value.startsWith(".")){
                    editText.setText("0.");
                }
                if(value.startsWith("0") && !value.startsWith("0.")){
                    editText.setText("");

                }


                String str = editText.getText().toString().replaceAll(",", "");
                if (!value.equals(""))
                editText.setText(getDecimalFormattedString(str));
                editText.setSelection(editText.getText().toString().length());
            }
            editText.addTextChangedListener(this);
            return;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            editText.addTextChangedListener(this);
        }

    }

    public static String getDecimalFormattedString(String value)
    {
        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++;
        }

    }

    public static String trimCommaOfString(String string) {
//        String returnString;
        if(string.contains(",")){
            return string.replace(",","");}
        else {
            return string;
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

使用此课程EditText如下

editText.addTextChangedListener(new NumberTextWatcherForThousand(editText));
Run Code Online (Sandbox Code Playgroud)

将输入作为普通双文本

trimCommaOfString像这样使用相同类的方法

NumberTextWatcherForThousand.trimCommaOfString(editText.getText().toString())
Run Code Online (Sandbox Code Playgroud)

混帐

  • 对于那些不使用英文形式的数字格式的人来说,这是_horrible_,所以欧洲,法国加拿大,南美洲,亚洲等的任何人都不应该使用硬编码的逗号,你应该查看DecimalFormatSymbols()并获取getGroupingSeparator ()代替.请记住,虽然美国和英国使用逗号数千和完全停止小数,但许多欧洲语言使用点数千和逗号的小数,其他人使用空格数千.请考虑多语言环境而不仅仅是您自己的. (6认同)

Dhe*_*.S. 37

你可以String.format()在一个TextWatcher.格式说明符中的逗号可以解决问题.

这不适用于浮点输入.并注意不要使用TextWatcher设置无限循环.

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
}
Run Code Online (Sandbox Code Playgroud)

  • 我无法理解你的意思//在临时删除文本更改监听器之后设置回视图,请你解释或完成该代码. (3认同)
  • 我希望千位分隔符出现在我实时输入的 EditText 上,而不是后面的字符串 (2认同)
  • 我的手机在运行此代码时崩溃,而不是应用程序,整个操作系统,不知道发生了什么, (2认同)

use*_*183 26

  public static String doubleToStringNoDecimal(double d) {
        DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);;
        formatter .applyPattern("#,###");
        return formatter.format(d);
    }
Run Code Online (Sandbox Code Playgroud)


Ada*_*itz 5

示例应用程序清楚地解构了格式化数字。

要总结以上链接,请使用,TextWatcher并在afterTextChanged()方法中EditText使用以下逻辑格式化视图:

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

    try {
        String originalString = s.toString();

        Long longval;
        if (originalString.contains(",")) {
            originalString = originalString.replaceAll(",", "");
        }
        longval = Long.parseLong(originalString);

        DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
        formatter.applyPattern("#,###,###,###");
        String formattedString = formatter.format(longval);

        //setting text after format to EditText
        editText.setText(formattedString);
        editText.setSelection(editText.getText().length());
    } catch (NumberFormatException nfe) {
        nfe.printStackTrace();
    }

    editText.addTextChangedListener(this);
}
Run Code Online (Sandbox Code Playgroud)


vla*_*zle 5

该解决方案比其他答案有一些优势。例如,即使用户编辑数字的开头或中间,它也会保留用户的光标位置。其他解决方案总是将光标跳到数字的末尾。它处理小数和整数,以及使用除.小数分隔符和,千位分组分隔符之外的字符的区域设置。

class SeparateThousands(val groupingSeparator: String, val decimalSeparator: String) : TextWatcher {

    private var busy = false

    override fun afterTextChanged(s: Editable?) {
        if (s != null && !busy) {
            busy = true

            var place = 0

            val decimalPointIndex = s.indexOf(decimalSeparator)
            var i = if (decimalPointIndex == -1) {
                s.length - 1
            } else {
                decimalPointIndex - 1
            }
            while (i >= 0) {
                val c = s[i]
                if (c == groupingSeparator[0] ) {
                    s.delete(i, i + 1)
                } else {
                    if (place % 3 == 0 && place != 0) {
                        // insert a comma to the left of every 3rd digit (counting from right to
                        // left) unless it's the leftmost digit
                        s.insert(i + 1, groupingSeparator)
                    }
                    place++
                }
                i--
            }

            busy = false
        }
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在xml中:

  <EditText
    android:id="@+id/myNumberField"
    android:digits=",.0123456789"
    android:inputType="numberDecimal"
    .../>
Run Code Online (Sandbox Code Playgroud)

最后注册观察者:

findViewById(R.id.myNumberField).addTextChangedListener(
    SeparateThousands(groupingSeparator, decimalSeparator))
Run Code Online (Sandbox Code Playgroud)

处理 。vs ,在不同的语言环境中使用 groupingSeparator 和decimalSeparator,它们可以来自 DecimalFormatSymbols 或本地化字符串。


dr0*_*pdb 5

我知道我参加聚会很晚,但它可能对未来的用户非常有用。我的回答是Shree Krishna回答的延伸。

改进:

  1. 千位分隔符和十进制标记是本地化的,即它们根据Locale设备的类型使用。
  2. 在中间删除或添加元素后,光标位置也不会改变(在他的回答中,光标已重置到末尾)。
  3. 代码的整体质量得到了特别的改进getDecimalFormattedString

代码:

    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: /sf/answers/2398578451/
     * 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,"");
        }
    }
Run Code Online (Sandbox Code Playgroud)