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

后端 未结 13 2050
花落未央
花落未央 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:45

    This solution has some advantage over other answers. For example, it keeps the user's cursor position even if they edit the beginning or middle of the number. Other solutions always jump the cursor to the end of the number. It handles decimals and whole numbers, as well as locales that use characters other than . for the decimal separator and , for the thousands grouping separator.

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

    Then in xml:

      
    

    And finally register the watcher:

    findViewById(R.id.myNumberField).addTextChangedListener(
        SeparateThousands(groupingSeparator, decimalSeparator))
    

    To handle . vs , in different locales use groupingSeparator and decimalSeparator, which can come from DecimalFormatSymbols or localized strings.

提交回复
热议问题