Android中使用千位分隔符(,)输入时如何格式化EditText的输入?

问题描述 投票:0回答:4

我有一个

edittext
,它只能获取没有小数的数字。

android:inputType="number"

我想在打字时将数千个分开。例如 25,000 。

我知道我应该使用

TextWatcher
并且我已经使用了这段代码,但我无法让它工作:

@Override
        public void afterTextChanged(Editable viewss) {
            String s = null;
            try {
                // The comma in the format specifier does the trick
                s = String.format("%,d", Long.parseLong(viewss.toString()));
            } catch (NumberFormatException e) {
            }

        }

你能帮我这样做吗?

java android android-edittext number-formatting textwatcher
4个回答
1
投票

将其添加到应用程序的 Gradle 中 编译 'com.aldoapps:autoformatedittext:0.9.3' 在 XML 中 xmlns:app =“http://schemas.android.com/apk/res-auto”

<com.aldoapps.autoformatedittext.AutoFormatEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:isDecimal="true"
    android:maxLength="8"
    android:id="@+id/number"/>

该库自动添加(,)(.)


1
投票
DecimalFormat formatter = new DecimalFormat("#,###,###");
String yourFormattedString = formatter.format(100000);

使用小数格式


1
投票

Kotlin 版本的 Adrian Cid Almageur 的评论

import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import java.text.DecimalFormat
import java.text.ParseException

class NumberTextWatcher(private val editText: EditText) : TextWatcher {

    private val decimalFormat = DecimalFormat("#,###.##")
    private val decimalFormatNoFrac = DecimalFormat("#,###")

    private var hasFractionalPart = false

    init {
        decimalFormat.isDecimalSeparatorAlwaysShown = true
    }

    override fun afterTextChanged(s: Editable?) {
        editText.removeTextChangedListener(this)

        try {
            val initialLength = editText.text.length

            val v = s.toString()
                .replace(decimalFormat.decimalFormatSymbols.groupingSeparator.toString(), "")
            val number = decimalFormat.parse(v)

            val cp = editText.selectionStart
            if (hasFractionalPart) {
                editText.setText(decimalFormat.format(number))
            } else {
                editText.setText(decimalFormatNoFrac.format(number))
            }
            val endLength = editText.length()
            val selection = (cp + (endLength - initialLength))
            if (selection > 0 && selection <= editText.text.length) {
                editText.setSelection(selection)
            } else {
                editText.setSelection(editText.text.length - 1)
            }
        } catch (nfe: NumberFormatException) {

        } catch (ex: ParseException) {

        }

        editText.addTextChangedListener(this)
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        hasFractionalPart =
            s.toString().contains(decimalFormat.decimalFormatSymbols.decimalSeparator)
    }

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

0
投票
com.google.android.material.textfield.TextInputEditText
android:inputType="number"
android:maxLines="1"
import android.icu.text.NumberFormat
import java.util.Locale

val editText = activityMainBinding.editText
var oldNumber = -1
var isRestart = false
editText.addTextChangedListener {
    //starts again when using "editText.setText()"
    if (isRestart) {
        isRestart = false
        return@addTextChangedListener
    }
    if (it.isNullOrEmpty()) {
        oldNumber = -1
        return@addTextChangedListener
    }

    //user writes 1 000 and user removed 1 and "toInt()" return 0
    val currentNumber = it.toString().replace(" ", "").toInt()

    //user writes 10 000 000 but will see 1 000 000, will see the previous number
    if (currentNumber > 1_000_0000) {
        val currentSelection = editText.selectionStart - 1
        val formatMoney = formatToMoney(oldNumber)
        isRestart = true
        editText.setText(formatMoney)
        editText.setSelection(currentSelection)
        return@addTextChangedListener
    }
    val currentSelection = editText.selectionStart

    //user writes 10 000 and user removed space and we delete 0 and user will see 1 000
    val newNumber =
        if (it[0] != '0' && currentNumber == oldNumber) {
            currentNumber.toString()
                .removeRange(currentSelection - 1, currentSelection)
                .toInt()
        } else currentNumber

    //user writes 00 but will see 0
    if (newNumber == 0) {
        oldNumber = -1
        isRestart = true
        editText.setText("0")
        editText.setSelection(1)
        return@addTextChangedListener
    }
    val formatMoney = formatToMoney(newNumber)

    //move selection one step forward or backward
    //when added a space -> step forward
    //when removed a space -> step backward
    val incOrDecSelection = formatMoney.length - it.length
    var newSelection = currentSelection + incOrDecSelection
 
    //user writes 1 000 and user remove 1 and "newSelection" will -1
    if (newSelection < 0) {
        newSelection = 0
    }
    oldNumber = newNumber
    isRestart = true
    editText.setText(formatMoney)
    editText.setSelection(newSelection)
}

//Need to use "Locale.US" different countries use different delimiters "," or "."
fun formatToMoney(number: Int): String {
    val formatMoney = NumberFormat.getNumberInstance(Locale.US).format(number)
    return formatMoney.replace(",", " ")
}

我们得到结果了
1 000
10 000
100 000
1 000 000

我在代码中写了注释。
您可以包装代码

try catch
并将异常发送到服务器,也许我错过了一些东西。

© www.soinside.com 2019 - 2024. All rights reserved.