在编辑文本中使用 numberDecimalinputType 小数点逗号(’,’)

EditText中的 inputType numberDecimal使用点 .作为小数点。在欧洲使用逗号 ,是很常见的。虽然我的地点设置为德国小数点仍然是 ABc3

有办法把逗号变成小数点吗?

140416 次浏览

这是 Android SDK 中的 已知窃听器。 唯一的解决办法是创建自己的软键盘。

一个解决方案(直到 Google 修复这个 bug)是使用 EditTextandroid:inputType="numberDecimal"以及 android:digits="0123456789.,"

然后在 EditText 中添加一个 TextChangedListener,其中包含以下内容:

public void afterTextChanged(Editable s) {
double doubleValue = 0;
if (s != null) {
try {
doubleValue = Double.parseDouble(s.toString().replace(',', '.'));
} catch (NumberFormatException e) {
//Error
}
}
//Do something with doubleValue
}

如果以编程方式实例化 EditText,则 Martins 回答不起作用。我继续修改了 API 14中包含的 DigitsKeyListener类,以允许逗号和句号作为小数点。

要使用这个函数,请在 EditText上调用 setKeyListener(),例如。

// Don't allow for signed input (minus), but allow for decimal points
editText.setKeyListener( new MyDigitsKeyListener( false, true ) );

但是,在 TextChangedListener中仍然需要使用 Martin 的技巧,即用句点代替逗号

import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.NumberKeyListener;
import android.view.KeyEvent;


class MyDigitsKeyListener extends NumberKeyListener {


/**
* The characters that are used.
*
* @see KeyEvent#getMatch
* @see #getAcceptedChars
*/
private static final char[][] CHARACTERS = new char[][] {
new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' },
new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' },
new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ',' },
new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', ',' },
};


private char[] mAccepted;
private boolean mSign;
private boolean mDecimal;


private static final int SIGN = 1;
private static final int DECIMAL = 2;


private static MyDigitsKeyListener[] sInstance = new MyDigitsKeyListener[4];


@Override
protected char[] getAcceptedChars() {
return mAccepted;
}


/**
* Allocates a DigitsKeyListener that accepts the digits 0 through 9.
*/
public MyDigitsKeyListener() {
this(false, false);
}


/**
* Allocates a DigitsKeyListener that accepts the digits 0 through 9,
* plus the minus sign (only at the beginning) and/or decimal point
* (only one per field) if specified.
*/
public MyDigitsKeyListener(boolean sign, boolean decimal) {
mSign = sign;
mDecimal = decimal;


int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);
mAccepted = CHARACTERS[kind];
}


/**
* Returns a DigitsKeyListener that accepts the digits 0 through 9.
*/
public static MyDigitsKeyListener getInstance() {
return getInstance(false, false);
}


/**
* Returns a DigitsKeyListener that accepts the digits 0 through 9,
* plus the minus sign (only at the beginning) and/or decimal point
* (only one per field) if specified.
*/
public static MyDigitsKeyListener getInstance(boolean sign, boolean decimal) {
int kind = (sign ? SIGN : 0) | (decimal ? DECIMAL : 0);


if (sInstance[kind] != null)
return sInstance[kind];


sInstance[kind] = new MyDigitsKeyListener(sign, decimal);
return sInstance[kind];
}


/**
* Returns a DigitsKeyListener that accepts only the characters
* that appear in the specified String.  Note that not all characters
* may be available on every keyboard.
*/
public static MyDigitsKeyListener getInstance(String accepted) {
// TODO: do we need a cache of these to avoid allocating?


MyDigitsKeyListener dim = new MyDigitsKeyListener();


dim.mAccepted = new char[accepted.length()];
accepted.getChars(0, accepted.length(), dim.mAccepted, 0);


return dim;
}


public int getInputType() {
int contentType = InputType.TYPE_CLASS_NUMBER;
if (mSign) {
contentType |= InputType.TYPE_NUMBER_FLAG_SIGNED;
}
if (mDecimal) {
contentType |= InputType.TYPE_NUMBER_FLAG_DECIMAL;
}
return contentType;
}


@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 (mSign == false && mDecimal == false) {
return out;
}


if (out != null) {
source = out;
start = 0;
end = out.length();
}


int sign = -1;
int decimal = -1;
int dlen = dest.length();


/*
* Find out if the existing text has '-' or '.' characters.
*/


for (int i = 0; i < dstart; i++) {
char c = dest.charAt(i);


if (c == '-') {
sign = i;
} else if (c == '.' || c == ',') {
decimal = i;
}
}
for (int i = dend; i < dlen; i++) {
char c = dest.charAt(i);


if (c == '-') {
return "";    // Nothing can be inserted in front of a '-'.
} else if (c == '.' ||  c == ',') {
decimal = i;
}
}


/*
* If it does, we must strip them out from the source.
* In addition, '-' must be the very first character,
* and nothing can be inserted before an existing '-'.
* Go in reverse order so the offsets are stable.
*/


SpannableStringBuilder stripped = null;


for (int i = end - 1; i >= start; i--) {
char c = source.charAt(i);
boolean strip = false;


if (c == '-') {
if (i != start || dstart != 0) {
strip = true;
} else if (sign >= 0) {
strip = true;
} else {
sign = i;
}
} else if (c == '.' || c == ',') {
if (decimal >= 0) {
strip = true;
} else {
decimal = i;
}
}


if (strip) {
if (end == start + 1) {
return "";  // Only one character, and it was stripped.
}


if (stripped == null) {
stripped = new SpannableStringBuilder(source, start, end);
}


stripped.delete(i - start, i + 1 - start);
}
}


if (stripped != null) {
return stripped;
} else if (out != null) {
return out;
} else {
return null;
}
}
}

用于 EditText 的代码货币掩码($123,125.155)

XML 布局

  <EditText
android:inputType="numberDecimal"
android:layout_height="wrap_content"
android:layout_width="200dp"
android:digits="0123456789.,$" />

密码

EditText testFilter=...
testFilter.addTextChangedListener( new TextWatcher() {
boolean isEdiging;
@Override public void onTextChanged(CharSequence s, int start, int before, int count) { }
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { }


@Override public void afterTextChanged(Editable s) {
if(isEdiging) return;
isEdiging = true;


String str = s.toString().replaceAll( "[^\\d]", "" );
double s1 = Double.parseDouble(str);


NumberFormat nf2 = NumberFormat.getInstance(Locale.ENGLISH);
((DecimalFormat)nf2).applyPattern("$ ###,###.###");
s.replace(0, s.length(), nf2.format(s1));


isEdiging = false;
}
});

您还可以使用以下解决方案将逗号作为有效输入包括在内:-

通过 XML:

<EditText
android:inputType="number"
android:digits="0123456789.," />

程序设计:

EditText input = new EditText(THE_CONTEXT);
input.setKeyListener(DigitsKeyListener.getInstance("0123456789.,"));

通过这种方式,Android 系统将显示数字的键盘,并允许输入逗号。希望这能回答这个问题:)

你可以这样做:

DecimalFormatSymbols d = DecimalFormatSymbols.getInstance(Locale.getDefault());
input.setFilters(new InputFilter[] { new DecimalDigitsInputFilter(5, 2) });
input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + d.getDecimalSeparator()));

然后你可以使用一个输入过滤器:

    public class DecimalDigitsInputFilter implements InputFilter {


Pattern mPattern;


public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) {
DecimalFormatSymbols d = new DecimalFormatSymbols(Locale.getDefault());
String s = "\\" + d.getDecimalSeparator();
mPattern = Pattern.compile("[0-9]{0," + (digitsBeforeZero - 1) + "}+((" + s + "[0-9]{0," + (digitsAfterZero - 1) + "})?)||(" + s + ")?");
}


@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {


Matcher matcher = mPattern.matcher(dest);
if (!matcher.matches())
return "";
return null;
}

}

对于 Mono (Droid)解决方案:

decimal decimalValue = decimal.Parse(input.Text.Replace(",", ".") , CultureInfo.InvariantCulture);

这里提供的“数字”解决方案的一个变体:

char separator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
input.setKeyListener(DigitsKeyListener.getInstance("0123456789" + separator));

考虑到区域设置分隔符。

我认为这个解决方案没有这里写的其他解决方案那么复杂:

<EditText
android:inputType="numberDecimal"
android:digits="0123456789," />

这样,当你在软键盘上按下“。”时,什么也不会发生; 只允许使用数字和逗号。

恕我直言,解决这个问题的最佳方法就是使用 InputFilter。一个不错的要点是在这里 十进制数字输入过滤器。然后你就可以:

editText.setInputType(TYPE_NUMBER_FLAG_DECIMAL | TYPE_NUMBER_FLAG_SIGNED | TYPE_CLASS_NUMBER)
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789,.-"))
editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});

Android 有一个内置的数字格式化程序。

您可以将此添加到 EditText以允许小数和逗号: android:inputType="numberDecimal"android:digits="0123456789.,"

然后在代码中的某个地方,当用户单击“保存”或在输入文本后(使用侦听器)。

// Format the number to the appropriate double
try {
Number formatted = NumberFormat.getInstance().parse(editText.getText().toString());
cost = formatted.doubleValue();
} catch (ParseException e) {
System.out.println("Error parsing cost string " + editText.getText().toString());
cost = 0.0;
}

您可以对不同的地区使用以下内容

private void localeDecimalInput(final EditText editText){


DecimalFormat decFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
DecimalFormatSymbols symbols=decFormat.getDecimalFormatSymbols();
final String defaultSeperator=Character.toString(symbols.getDecimalSeparator());


editText.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 editable) {
if(editable.toString().contains(defaultSeperator))
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789"));
else
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789" + defaultSeperator));
}
});
}

使输入本地化:

char sep = DecimalFormatSymbols.getInstance().getDecimalSeparator();

然后加上:

textEdit.setKeyListener(DigitsKeyListener.getInstance("0123456789" + sep));

不要忘记用“替换”,这样 Float 或 Double 就可以解析它而不会出现错误。

我决定在编辑的时候把逗号改成点。下面是我的技巧和相对简单的解决办法:

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
EditText editText = (EditText) v;
String text = editText.getText().toString();
if (hasFocus) {
editText.setText(text.replace(",", "."));
} else {
if (!text.isEmpty()) {
Double doubleValue = Double.valueOf(text.replace(",", "."));
editText.setText(someDecimalFormatter.format(doubleValue));
}
}
}
});

Some DecimalFormatter 将使用逗号或点取决于语言环境

我不知道你的答案为什么这么复杂。如果 SDK 中有一个 bug,你必须覆盖它或者绕过它。

我选择了第二种方法来解决这个问题。如果您将字符串格式化为 Locale.ENGLISH,然后将其放到 EditText(即使是空字符串)。例如:

String.format(Locale.ENGLISH,"%.6f", yourFloatNumber);

追踪该解决方案,您的结果与显示的键盘兼容。然后浮点数和双数以编程语言的典型方式使用点代替逗号。

我的解决办法是:

  • 主要活动:

    Char 分隔符 = DecimalFormatSymbols.getInstance () SetKeyListener (DigitsKeyListener.getInstance (“0123456789”+ 分隔符)) ;

  • 在 xml 文件中: ImOptions = “ Flag NoFullscreen” InputType = “ numberDecimal”

然后我把 edText 中的 double 作为 String。

我可以证实,修复建议不工作的三星 IME (至少在 S6和 S9) ,也许 LG。它们仍然显示一个点作为小数点,而不考虑地点。切换到谷歌的 IME 可以解决这个问题,但对大多数开发人员来说,这几乎不是一个选择。

在 Oreo,这些键盘也没有得到修复,因为这是三星和/或 LG 不得不做的修复工作,然后甚至推向他们的老式手机。

相反,我分叉了 数字键盘计划数字键盘计划并添加了一个模式,其行为类似于 IME: 叉子。有关详细信息,请参阅项目示例。这对我来说非常有效,就像你在银行应用程序中看到的许多“ PIN 输入”假 IME 一样。

Sample app screenshot

八年多过去了,我很惊讶,这个问题还没有解决..。
我纠结于这个简单的问题,因为 < strong >@Martin 的最受欢迎的答案允许输入多个分隔符,也就是说用户可以输入“12,,,,12,1,,21,2,”
此外,第二个问题是,在一些设备上,逗号没有显示在数字键盘上(或者需要多次按点按钮)

这是我的解决方案,它解决了上面提到的问题,并让用户输入’“ ,”,但是在编辑文本中,他将看到与当前地区相对应的唯一小数点:

editText.apply { addTextChangedListener(DoubleTextChangedListener(this)) }

还有那个看短信的:

  open class DoubleTextChangedListener(private val et: EditText) : TextWatcher {


init {
et.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
et.keyListener = DigitsKeyListener.getInstance("0123456789.,")
}


private val separator = DecimalFormatSymbols.getInstance().decimalSeparator


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


@CallSuper
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
et.run {
removeTextChangedListener(this@DoubleTextChangedListener)
val formatted = toLocalizedDecimal(s.toString(), separator)
setText(formatted)
setSelection(formatted.length)
addTextChangedListener(this@DoubleTextChangedListener)
}
}


override fun afterTextChanged(s: Editable?) {
// empty
}


/**
* Formats input to a decimal. Leaves the only separator (or none), which matches [separator].
* Examples:
* 1. [s]="12.12", [separator]=',' -> result= "12,12"
* 2. [s]="12.12", [separator]='.' -> result= "12.12"
* 4. [s]="12,12", [separator]='.' -> result= "12.12"
* 5. [s]="12,12,,..,,,,,34..,", [separator]=',' -> result= "12,1234"
* 6. [s]="12.12,,..,,,,,34..,", [separator]='.' -> result= "12.1234"
* 7. [s]="5" -> result= "5"
*/
private fun toLocalizedDecimal(s: String, separator: Char): String {
val cleared = s.replace(",", ".")
val splitted = cleared.split('.').filter { it.isNotBlank() }
return when (splitted.size) {
0 -> s
1 -> cleared.replace('.', separator).replaceAfter(separator, "")
2 -> splitted.joinToString(separator.toString())
else -> splitted[0]
.plus(separator)
.plus(splitted.subList(1, splitted.size - 1).joinToString(""))
}
}
}

简单的解决方案,制作一个自定义控件(这是 Xamarin android 制造的,但应该很容易移植到 java)

public class EditTextDecimalNumber:EditText
{
readonly string _numberFormatDecimalSeparator;


public EditTextDecimalNumber(Context context, IAttributeSet attrs) : base(context, attrs)
{
InputType = InputTypes.NumberFlagDecimal;
TextChanged += EditTextDecimalNumber_TextChanged;
_numberFormatDecimalSeparator = System.Threading.Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator;


KeyListener = DigitsKeyListener.GetInstance($"0123456789{_numberFormatDecimalSeparator}");
}


private void EditTextDecimalNumber_TextChanged(object sender, TextChangedEventArgs e)
{
int noOfOccurence = this.Text.Count(x => x.ToString() == _numberFormatDecimalSeparator);
if (noOfOccurence >=2)
{
int lastIndexOf = this.Text.LastIndexOf(_numberFormatDecimalSeparator,StringComparison.CurrentCulture);
if (lastIndexOf!=-1)
{
this.Text = this.Text.Substring(0, lastIndexOf);
this.SetSelection(this.Text.Length);
}


}
}
}

这里所有其他的帖子都有很大的漏洞,所以这里有一个解决方案:

  • 强制使用基于区域的逗号或句号,将不允许您键入相反的一个。
  • 如果 EditText 以某个值开始,它将根据需要替换正确的分隔符。

在 XML 中:

<EditText
...
android:inputType="numberDecimal"
... />

类变量:

private boolean isDecimalSeparatorComma = false;

在 onCreate 中,找到当前语言环境中使用的分隔符:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
NumberFormat nf = NumberFormat.getInstance();
if (nf instanceof DecimalFormat) {
DecimalFormatSymbols sym = ((DecimalFormat) nf).getDecimalFormatSymbols();
char decSeparator = sym.getDecimalSeparator();
isDecimalSeparatorComma = Character.toString(decSeparator).equals(",");
}
}

还有 onCreate,如果你正在加载一个当前值,可以用这个来更新它:

// Replace editText with commas or periods as needed for viewing
String editTextValue = getEditTextValue(); // load your current value
if (editTextValue.contains(".") && isDecimalSeparatorComma) {
editTextValue = editTextValue.replaceAll("\\.",",");
} else if (editTextValue.contains(",") && !isDecimalSeparatorComma) {
editTextValue = editTextValue.replaceAll(",",".");
}
setEditTextValue(editTextValue); // override your current value

还可以创建、添加监听器

editText.addTextChangedListener(editTextWatcher);


if (isDecimalSeparatorComma) {
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789,"));
} else {
editText.setKeyListener(DigitsKeyListener.getInstance("0123456789."));
}

EditTextWatcher 编辑 TextWatcher

TextWatcher editTextWatcher = 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) {
String editTextValue = s.toString();


// Count up the number of commas and periods
Pattern pattern = Pattern.compile("[,.]");
Matcher matcher = pattern.matcher(editTextValue);
int count = 0;
while (matcher.find()) {
count++;
}


// Don't let it put more than one comma or period
if (count > 1) {
s.delete(s.length()-1, s.length());
} else {
// If there is a comma or period at the end the value hasn't changed so don't update
if (!editTextValue.endsWith(",") && !editTextValue.endsWith(".")) {
doSomething()
}
}
}
};

例如,转换为数据操作的标准周期

private void doSomething() {
try {
String editTextStr = editText.getText().toString();
if (isDecimalSeparatorComma) {
editTextStr = editTextStr.replaceAll(",",".");
}
float editTextFloatValue = editTextStr.isEmpty() ?
0.0f :
Float.valueOf(editTextStr);


... use editTextFloatValue
} catch (NumberFormatException e) {
Log.e(TAG, "Error converting String to Double");
}
}

您可以使用 inputType="phone",但是在这种情况下,您必须处理存在多个 ,.的问题,因此需要进行额外的验证。

我为 KOTLIN 准备的

我也遇到了同样的问题,我解决了:

val separator = DecimalFormatSymbols.getInstance().decimalSeparator
mEditText.keyListener = DigitsKeyListener.getInstance("0123456789$separator")

而且效果很好。!但是!在三星键盘上,分隔符没有显示,所以你不能输入十进制数。

所以我必须通过检查来解决这个问题,如果使用三星键盘:

    val x = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
if (x.toLowerCase().contains("samsung")) {}
  

但是你仍然有“作为小数点。因此,如果分隔符是逗号,你必须用逗号替换点:

val separator: Char = DecimalFormatSymbols.getInstance().decimalSeparator
 

if (separator == ',') {
mEditText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
    

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit
    

override fun afterTextChanged(s: Editable?) {
    

if (!s.isNullOrEmpty()) {
                                

if (s.toString().contains(".")) {
val replaced = s.toString().replace('.', separator)
mEditText.setText(replaced)
mEditText.setSelection(replaced.length)
}
    

                                

}
}
})
}

但是,您必须检查 EditTextfield 中是否没有人键入更多的“”。这可以用正则表达式来完成。

我的整个解决方案:

val x = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
if (x.toLowerCase().contains("samsung")) {
val Number_REGEX: Pattern =  Pattern.compile("^([1-9])*([.,]{1}[0-9]{0,10})?$")
val separator: Char = DecimalFormatSymbols.getInstance().decimalSeparator
if (separator == ',') {
mEditText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit


override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit


override fun afterTextChanged(s: Editable?) {


if (!s.isNullOrEmpty()) {
val matcherMail = Number_REGEX.matcher(s.toString())
if (!matcherMail.matches()) {
val length: Int = s.length


s.delete(length - 1, length);
} else {
if (s.toString().contains(".")) {
val replaced = s.toString().replace('.', separator)
mEditText.setText(replaced)
mEditText.setSelection(replaced.length)
}


}
}
}
})
}
} else {
val separator = DecimalFormatSymbols.getInstance().decimalSeparator
mEditText.keyListener = DigitsKeyListener.getInstance("0123456789$separator")
       

}

Xml 文件:

 <com.google.android.material.textfield.TextInputEditText
android:id="@+id/tEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Input"
android:inputType="numberDecimal"
android:imeOptions="actionDone"/>

如果你想使用这个数字,一定要选择正确的格式:

val x = NumberFormat.getInstance().parse(mEditText.text.toString()).toDouble()

我有一个解决方案,允许用户输入点和逗号(如果键盘上有的话) ,但只显示区域设置默认分隔符。此外,它不允许用户输入多于1个分隔符。对 EditText或无限循环的引用没有问题。这是一个在这个线程适合我的需要的几个答案的组合。

与已接受的答案一样,相应地配置 EditText:

android:inputType="numberDecimal"
android:digits="0123456789.,"

然后在 EditText 上设置一个自定义 TextWatcher:

myEditText.addTextChangedListener(FlexibleDecimalSeparatorTextWatcher())

还包括定制的 TextWatcher:

import android.text.Editable
import android.text.SpannableStringBuilder
import android.text.TextWatcher
import android.widget.EditText
import java.text.DecimalFormatSymbols


/**
* The [FlexibleDecimalSeparatorTextWatcher] allows the user to input both the comma (,) and dot (.) as a decimal separator,
* and will then automatically convert each entered separator into the locale default separator.
* If the user were to enter multiple separators - every separator but the first will be removed.
*
* To provide comma and dot support, set the [EditText] inputType to 'numberDecimal' and its digits to '0123456789.,'.
*/
class FlexibleDecimalSeparatorTextWatcher : TextWatcher {
companion object {
private val DECIMAL_SEPARATORS = listOf('.', ',')
private val LOCALE_DEFAULT_DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance().decimalSeparator
}


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


override fun afterTextChanged(s: Editable?) {
if (s != null) {
val textWithConvertedSeparators = convertSeparatorsToLocaleDefault(s.toString())
val textWithoutMultipleSeparators = removeAdditionalSeparators(textWithConvertedSeparators)


// Make the change if required. This only triggers one additional afterTextChanged call if there were changes.
if(s.toString() != textWithoutMultipleSeparators) {
s.replace(0, s.length, SpannableStringBuilder(textWithoutMultipleSeparators))
}
}
}


/**
* This function converts all entered separators (in [DECIMAL_SEPARATORS]) to the [LOCALE_DEFAULT_DECIMAL_SEPARATOR].
*/
private fun convertSeparatorsToLocaleDefault(original: String): String {
var result = original
DECIMAL_SEPARATORS.forEach { separator ->
if (separator != LOCALE_DEFAULT_DECIMAL_SEPARATOR && result.contains(separator)) {
result = result.replace(separator, LOCALE_DEFAULT_DECIMAL_SEPARATOR)
}
}
return result
}


/**
* Strip out all separators but the first.
* In this function we assume all separators are already converted to the locale default.
*/
private fun removeAdditionalSeparators(original: String): String {
var result = original
var separatorCount = result.count { c -> c == LOCALE_DEFAULT_DECIMAL_SEPARATOR }
if(separatorCount > 1) {
// We will reverse the text so we can keep stripping the last (first in reverse) separator off.
var textReversed = result.reversed()
val separatorRegex = Regex.fromLiteral(LOCALE_DEFAULT_DECIMAL_SEPARATOR.toString())
while (separatorCount > 1) {
textReversed = textReversed.replaceFirst(separatorRegex, "")
separatorCount--
}
// And finally we reverse it back to the original order.
result = textReversed.reversed()
}
return result
}

}

我不得不想出一个对我有利的办法,那就是把不同的答案混合在一起。 这将允许“ ,”或“。”最多为一个小数

这是我的编辑:

val separator: Char = DecimalFormatSymbols.getInstance().decimalSeparator
editTextBox.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(5, 1, separator))
editTextBox.keyListener = DigitsKeyListener.getInstance("0123456789$separator")

和我的类来处理特定的正则表达式:

class DecimalDigitsInputFilter(
digitsBeforeZero: Int,
digitsAfterZero: Int,
separator: Char
) : InputFilter {
private val mPattern: Pattern =
Pattern.compile("[0-9]{0," + (digitsBeforeZero - 1) + "}+((\\$separator[0-9]{0," + (digitsAfterZero - 1) + "})?)||(\\$separator)?")


override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence? {
val matcher = mPattern.matcher(dest)
return if (!matcher.matches()) "" else null
}
}