限制Android EditText中的小数位数

Kon*_*itz 119 java android android-edittext

我正在尝试编写一款可以帮助您管理财务状况的应用.我正在使用一个EditText用户可以指定金额的字段.

我设置inputTypenumberDecimal其工作正常,但,这让人们输入数字,如123.122这是不完美的钱.

有没有办法将小数点后的字符数限制为两个?

Asa*_*ssi 108

更优雅的方式是使用正则表达式(正则表达式),如下所示:

public class DecimalDigitsInputFilter implements InputFilter {

Pattern mPattern;

public DecimalDigitsInputFilter(int digitsBeforeZero,int digitsAfterZero) {
    mPattern=Pattern.compile("[0-9]{0," + (digitsBeforeZero-1) + "}+((\\.[0-9]{0," + (digitsAfterZero-1) + "})?)||(\\.)?");
}

@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;
    }

}
Run Code Online (Sandbox Code Playgroud)

使用它做:

editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});
Run Code Online (Sandbox Code Playgroud)

  • 嗨,有些边缘情况仍然没有得到很好的处理.例如,在我键入2.45之后,我倾向于"将光标移动到文本的最前面".我希望制作文本12.45,它不会允许. (32认同)
  • 很好的解决方案,但它完全不正确.匹配器不应该检查dest,它应该检查edittext中的值(dest.subSequence(0,dstart)+ source.subSequence(start,end)+ dest.subSequence(dend,dest.length())) (9认同)
  • Mihaela是对的,我们应该匹配试图填充edittext的字符串.我发现如何连接另一个问题,如CharSequence match = TextUtils.concat(dest.subSequence(0,dstart),source.subSequence(start,end),dest.subSequence(dend,dest.length())); 正则表达式之后引起了问题,所以我把它改成了这个"^ \\ d {1,"+ digitsBeforeZero +"}(\\.\\ d {0,"+ digitsAfterZero +"})?$"但是你'之后我也要做验证,因为"1" 对于那个正则表达式是有效的,但我们需要这样,所以可以输入句点. (7认同)
  • 你会如何为逗号(,)做这个工作?世界上的某些地区用逗号键入十进制数字(例如:123,45). (6认同)
  • 用户在小数点后输入2位数后,不允许在小数点前更改数字. (3认同)
  • 错误的解决方案。如果您将 `digitsBeforeZero` 设置为 1 并将 `digitsAfterZero` 设置为 3,则无法正常工作,您将无法在小数点 (. dot) 后键入 3 位数字 (2认同)

pec*_*eps 63

更简单的解决方案,不使用正则表达式:

import android.text.InputFilter;
import android.text.Spanned;

/**
 * Input filter that limits the number of decimal digits that are allowed to be
 * entered.
 */
public class DecimalDigitsInputFilter implements InputFilter {

  private final int decimalDigits;

  /**
   * Constructor.
   * 
   * @param decimalDigits maximum decimal digits
   */
  public DecimalDigitsInputFilter(int decimalDigits) {
    this.decimalDigits = decimalDigits;
  }

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


    int dotPos = -1;
    int len = dest.length();
    for (int i = 0; i < len; i++) {
      char c = dest.charAt(i);
      if (c == '.' || c == ',') {
        dotPos = i;
        break;
      }
    }
    if (dotPos >= 0) {

      // protects against many dots
      if (source.equals(".") || source.equals(","))
      {
          return "";
      }
      // if the text is entered before the dot
      if (dend <= dotPos) {
        return null;
      }
      if (len - dotPos > decimalDigits) {
        return "";
      }
    }

    return null;
  }

}
Run Code Online (Sandbox Code Playgroud)

使用:

editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(2)});
Run Code Online (Sandbox Code Playgroud)

  • 这不处理我键入"999"然后在前9后插入小数点的情况. (6认同)
  • 这:<EditText ... android:inputType ="number"/> (4认同)

Kon*_*itz 33

这种实现InputFilter解决了这个问题.

import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.DigitsKeyListener;

public class MoneyValueFilter extends DigitsKeyListener {
    public MoneyValueFilter() {
        super(false, true);
    }

    private int digits = 2;

    public void setDigits(int d) {
        digits = d;
    }

    @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 changed, replace the source
        if (out != null) {
            source = out;
            start = 0;
            end = out.length();
        }

        int len = end - start;

        // if deleting, source is empty
        // and deleting can't break anything
        if (len == 0) {
            return source;
        }

        int dlen = dest.length();

        // Find the position of the decimal .
        for (int i = 0; i < dstart; i++) {
            if (dest.charAt(i) == '.') {
                // being here means, that a number has
                // been inserted after the dot
                // check if the amount of digits is right
                return (dlen-(i+1) + len > digits) ? 
                    "" :
                    new SpannableStringBuilder(source, start, end);
            }
        }

        for (int i = start; i < end; ++i) {
            if (source.charAt(i) == '.') {
                // being here means, dot has been inserted
                // check if the amount of digits is right
                if ((dlen-dend) + (end-(i + 1)) > digits)
                    return "";
                else
                    break;  // return new SpannableStringBuilder(source, start, end);
            }
        }

        // if the dot is after the inserted part,
        // nothing can break
        return new SpannableStringBuilder(source, start, end);
    }
}
Run Code Online (Sandbox Code Playgroud)


Fav*_* Kv 33

下面是一个示例InputFilter,它只允许小数点前最多4位数,之后最多1位数.

价值观是允许的EditText:555.2,555,0.2

这EDITTEXT块值:55555.2,055.2,555.42

        InputFilter filter = new InputFilter() {
        final int maxDigitsBeforeDecimalPoint=4;
        final int maxDigitsAfterDecimalPoint=1;

        @Override
        public CharSequence filter(CharSequence source, int start, int end,
                Spanned dest, int dstart, int dend) {
                StringBuilder builder = new StringBuilder(dest);
                builder.replace(dstart, dend, source
                        .subSequence(start, end).toString());
                if (!builder.toString().matches(
                        "(([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?"

                        )) {
                    if(source.length()==0)
                        return dest.subSequence(dstart, dend);
                    return "";
                }

            return null;

        }
    };

    mEdittext.setFilters(new InputFilter[] { filter });
Run Code Online (Sandbox Code Playgroud)


and*_*dev 19

我为@Pinhassi解决方案做了一些修复.它处理一些情况:

1.你可以将光标移动到任何地方

2.minus标志处理

3.digitsbefore = 2和digitsafter = 4,然后输入12.4545.然后,如果你想删除".",它将不允许.

public class DecimalDigitsInputFilter implements InputFilter {
    private int mDigitsBeforeZero;
    private int mDigitsAfterZero;
    private Pattern mPattern;

    private static final int DIGITS_BEFORE_ZERO_DEFAULT = 100;
    private static final int DIGITS_AFTER_ZERO_DEFAULT = 100;

    public DecimalDigitsInputFilter(Integer digitsBeforeZero, Integer digitsAfterZero) {
    this.mDigitsBeforeZero = (digitsBeforeZero != null ? digitsBeforeZero : DIGITS_BEFORE_ZERO_DEFAULT);
    this.mDigitsAfterZero = (digitsAfterZero != null ? digitsAfterZero : DIGITS_AFTER_ZERO_DEFAULT);
    mPattern = Pattern.compile("-?[0-9]{0," + (mDigitsBeforeZero) + "}+((\\.[0-9]{0," + (mDigitsAfterZero)
        + "})?)||(\\.)?");
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    String replacement = source.subSequence(start, end).toString();
    String newVal = dest.subSequence(0, dstart).toString() + replacement
        + dest.subSequence(dend, dest.length()).toString();
    Matcher matcher = mPattern.matcher(newVal);
    if (matcher.matches())
        return null;

    if (TextUtils.isEmpty(source))
        return dest.subSequence(dstart, dend);
    else
        return "";
    }
}
Run Code Online (Sandbox Code Playgroud)


Gun*_*lan 17

我通过TextWatcher以下方式帮助实现了这一目标

final EditText et = (EditText) findViewById(R.id.EditText1);
et.addTextChangedListener(new TextWatcher() {
    public void onTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {             

    }
    public void beforeTextChanged(CharSequence arg0, int arg1,int arg2, int arg3) {             

    }

    public void afterTextChanged(Editable arg0) {
        if (arg0.length() > 0) {
            String str = et.getText().toString();
            et.setOnKeyListener(new OnKeyListener() {
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        count--;
                        InputFilter[] fArray = new InputFilter[1];
                        fArray[0] = new InputFilter.LengthFilter(100);
                        et.setFilters(fArray);
                        //change the edittext's maximum length to 100. 
                        //If we didn't change this the edittext's maximum length will
                        //be number of digits we previously entered.
                    }
                    return false;
                }
            });
            char t = str.charAt(arg0.length() - 1);
            if (t == '.') {
                count = 0;
            }
            if (count >= 0) {
                if (count == 2) {                        
                    InputFilter[] fArray = new InputFilter[1];
                    fArray[0] = new InputFilter.LengthFilter(arg0.length());
                    et.setFilters(fArray);
                    //prevent the edittext from accessing digits 
                    //by setting maximum length as total number of digits we typed till now.
                }
                count++;
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

此解决方案不允许用户在小数点后输入两位以上的数字.您也可以在小数点前输入任意位数.请参阅此博客http://v4all123.blogspot.com/2013/05/set-limit-for-fraction-in-decimal.html为多个EditText设置过滤器.我希望这将有所帮助.谢谢.


Apo*_*leo 13

我不喜欢其他解决方案而且我创建了自己的解决方案.使用此解决方案,您不能在该点之前输入超过MAX_BEFORE_POINT数字,并且小数不能超过MAX_DECIMAL.

你只是不能输入过多的数字,没有其他影响!另外如果你写"." 它输入"0"

  1. 将布局中的EditText设置为:

    安卓的inputType = "numberDecimal"

  2. 在onCreate中添加监听器.如果你想修改点之前和之后的数字编辑调用PerfectDecimal(str,NUMBER_BEFORE_POINT,NUMBER_DECIMALS),这里设置为3和2

    EditText targetEditText = (EditText)findViewById(R.id.targetEditTextLayoutId);
    
    targetEditText.addTextChangedListener(new TextWatcher() {
      public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
    
      public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}
    
      public void afterTextChanged(Editable arg0) {
        String str = targetEditText.getText().toString();
        if (str.isEmpty()) return;
        String str2 = PerfectDecimal(str, 3, 2);
    
        if (!str2.equals(str)) {
            targetEditText.setText(str2);
            int pos = targetEditText.getText().length();
            targetEditText.setSelection(pos);
        }
      }
    });
    
    Run Code Online (Sandbox Code Playgroud)
  3. 包括这个Funcion:

    public String PerfectDecimal(String str, int MAX_BEFORE_POINT, int MAX_DECIMAL){
      if(str.charAt(0) == '.') str = "0"+str;
      int max = str.length();
    
      String rFinal = "";
      boolean after = false;
      int i = 0, up = 0, decimal = 0; char t;
      while(i < max){
        t = str.charAt(i);
        if(t != '.' && after == false){
            up++;
            if(up > MAX_BEFORE_POINT) return rFinal;
        }else if(t == '.'){
            after = true;
        }else{
            decimal++;
            if(decimal > MAX_DECIMAL)
                return rFinal;
        }
        rFinal = rFinal + t;
        i++;
      }return rFinal;
    }
    
    Run Code Online (Sandbox Code Playgroud)

它已经完成了!


Dom*_*icz 11

我的解决方案很简单,工作完美!

public class DecimalInputTextWatcher implements TextWatcher {

private String mPreviousValue;
private int mCursorPosition;
private boolean mRestoringPreviousValueFlag;
private int mDigitsAfterZero;
private EditText mEditText;

public DecimalInputTextWatcher(EditText editText, int digitsAfterZero) {
    mDigitsAfterZero = digitsAfterZero;
    mEditText = editText;
    mPreviousValue = "";
    mRestoringPreviousValueFlag = false;
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    if (!mRestoringPreviousValueFlag) {
        mPreviousValue = s.toString();
        mCursorPosition = mEditText.getSelectionStart();
    }
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}

@Override
public void afterTextChanged(Editable s) {
    if (!mRestoringPreviousValueFlag) {

        if (!isValid(s.toString())) {
            mRestoringPreviousValueFlag = true;
            restorePreviousValue();
        }

    } else {
        mRestoringPreviousValueFlag = false;
    }
}

private void restorePreviousValue() {
    mEditText.setText(mPreviousValue);
    mEditText.setSelection(mCursorPosition);
}

private boolean isValid(String s) {
    Pattern patternWithDot = Pattern.compile("[0-9]*((\\.[0-9]{0," + mDigitsAfterZero + "})?)||(\\.)?");
    Pattern patternWithComma = Pattern.compile("[0-9]*((,[0-9]{0," + mDigitsAfterZero + "})?)||(,)?");

    Matcher matcherDot = patternWithDot.matcher(s);
    Matcher matcherComa = patternWithComma.matcher(s);

    return matcherDot.matches() || matcherComa.matches();
}
}
Run Code Online (Sandbox Code Playgroud)

用法:

myTextEdit.addTextChangedListener(new DecimalInputTextWatcher(myTextEdit, 2));
Run Code Online (Sandbox Code Playgroud)


Man*_*esh 11

要求是十进制后的2位数.小数点前的数字应该没有限制.所以,解决方案应该是,

public class DecimalDigitsInputFilter implements InputFilter {

    Pattern mPattern;

    public DecimalDigitsInputFilter() {
        mPattern = Pattern.compile("[0-9]*+((\\.[0-9]?)?)||(\\.)?");
    }

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

用它作为,

mEditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter()});
Run Code Online (Sandbox Code Playgroud)

感谢@Pinhassi的灵感.

  • 很好...工作正常 (2认同)

Luk*_*uke 11

我想出的InputFilter允许您配置小数位前后的位数.此外,它不允许前导零.

public class DecimalDigitsInputFilter implements InputFilter
{
    Pattern pattern;

    public DecimalDigitsInputFilter(int digitsBeforeDecimal, int digitsAfterDecimal)
    {
        pattern = Pattern.compile("(([1-9]{1}[0-9]{0," + (digitsBeforeDecimal - 1) + "})?||[0]{1})((\\.[0-9]{0," + digitsAfterDecimal + "})?)||(\\.)?");
    }

    @Override public CharSequence filter(CharSequence source, int sourceStart, int sourceEnd, Spanned destination, int destinationStart, int destinationEnd)
    {
        // Remove the string out of destination that is to be replaced.
        String newString = destination.toString().substring(0, destinationStart) + destination.toString().substring(destinationEnd, destination.toString().length());

        // Add the new string in.
        newString = newString.substring(0, destinationStart) + source.toString() + newString.substring(destinationStart, newString.length());

        // Now check if the new string is valid.
        Matcher matcher = pattern.matcher(newString);

        if(matcher.matches())
        {
            // Returning null indicates that the input is valid.
            return null;
        }

        // Returning the empty string indicates the input is invalid.
        return "";
    }
}

// To use this InputFilter, attach it to your EditText like so:
final EditText editText = (EditText) findViewById(R.id.editText);

EditText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(4, 4)});
Run Code Online (Sandbox Code Playgroud)


小智 7

实现这一目标的最简单方法是:

et.addTextChangedListener(new TextWatcher() {
    public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        String text = arg0.toString();
        if (text.contains(".") && text.substring(text.indexOf(".") + 1).length() > 2) {
            et.setText(text.substring(0, text.length() - 1));
            et.setSelection(et.getText().length());
        }
    }

    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

    }

    public void afterTextChanged(Editable arg0) {
    }
});
Run Code Online (Sandbox Code Playgroud)


Mat*_*lis 6

在将字符串放入TextView之前,请尝试使用NumberFormat.getCurrencyInstance()格式化字符串.

就像是:

NumberFormat currency = NumberFormat.getCurrencyInstance();
myTextView.setText(currency.format(dollars));
Run Code Online (Sandbox Code Playgroud)

编辑 - 我没有在文档中找到的货币输入类型.我想这是因为有些货币不遵循相同的小数位规则,例如日元.

作为LeffelMania提到的,您可以使用上面的代码与正确的用户输入TextWatcher是在你的设置EditText.


pix*_*xel 6

稍微改进了@Pinhassi解决方案.

效果很好.它验证连接的字符串.

public class DecimalDigitsInputFilter implements InputFilter {

Pattern mPattern;

public DecimalDigitsInputFilter() {
    mPattern = Pattern.compile("([1-9]{1}[0-9]{0,2}([0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)");

}

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

    String formatedSource = source.subSequence(start, end).toString();

    String destPrefix = dest.subSequence(0, dstart).toString();

    String destSuffix = dest.subSequence(dend, dest.length()).toString();

    String result = destPrefix + formatedSource + destSuffix;

    result = result.replace(",", ".");

    Matcher matcher = mPattern.matcher(result);

    if (matcher.matches()) {
        return null;
    }

    return "";
}

 }
Run Code Online (Sandbox Code Playgroud)


小智 6

我已修改上述解决方案并创建了以下解决方案.您可以设置小数点前后的位数.

public class DecimalDigitsInputFilter implements InputFilter {

private final Pattern mPattern;

public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) {
    mPattern = Pattern.compile(String.format("[0-9]{0,%d}(\\.[0-9]{0,%d})?", digitsBeforeZero, digitsAfterZero));
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    Matcher matcher = mPattern.matcher(createResultString(source, start, end, dest, dstart, dend));
    if (!matcher.matches())
        return "";
    return null;
}

private String createResultString(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    String sourceString = source.toString();
    String destString = dest.toString();
    return destString.substring(0, dstart) + sourceString.substring(start, end) + destString.substring(dend);
}
Run Code Online (Sandbox Code Playgroud)

}


小智 6

在 Android kotlin 中创建一个名为 DecimalDigitsInputFilter 的新类

class DecimalDigitsInputFilter(digitsBeforeDecimal: Int, digitsAfterDecimal: Int) : InputFilter {

    var mPattern: Pattern = Pattern.compile("[0-9]{0,$digitsBeforeDecimal}+((\\.[0-9]{0,$digitsAfterDecimal})?)||(\\.)?")

    override fun filter(
        source: CharSequence?,
        start: Int,
        end: Int,
        dest: Spanned?,
        dstart: Int,
        dend: Int
    ): CharSequence? {
        val matcher: Matcher = mPattern.matcher(
            dest?.subSequence(0, dstart).toString() + source?.subSequence(
                start,
                end
            ).toString() + dest?.subSequence(dend, dest.length).toString()
        )
        if (!matcher.matches())
            return ""
        else
            return null
    }
}
Run Code Online (Sandbox Code Playgroud)

使用以下行调用此类

 et_buy_amount.filters = (arrayOf<InputFilter>(DecimalDigitsInputFilter(8,2)))
Run Code Online (Sandbox Code Playgroud)

有太多相同的答案,但它允许您输入小数点前 8 位数字和小数点后 2 位数字

其他答案只接受 8 位数字


Sip*_*pka 5

DecimalFormat form = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US));
    EditText et; 
    et.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

        if (actionId == EditorInfo.IME_ACTION_DONE) {
            double a = Double.parseDouble(et.getText().toString());
            et.setText(form.format(a));
        }
        return false;
    }
});
Run Code Online (Sandbox Code Playgroud)

这样做是当您退出编辑阶段时,它将字段格式化为正确的格式。目前,它只有 2 个十进制字符。我认为这是很容易做到这一点的方法。


Dav*_*rry 5

我真的很喜欢 Pinhassi 的答案,但注意到用户在小数点后输入了指定的数字后,您无法再在小数点左侧输入文本。问题在于该解决方案仅测试之前输入的文本,而不测试当前输入的文本。所以这是我的解决方案,它将新字符插入原始文本中进行验证。

package com.test.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;

public class InputFilterCurrency implements InputFilter {
    Pattern moPattern;

    public InputFilterCurrency(int aiMinorUnits) {
        // http://www.regexplanet.com/advanced/java/index.html
        moPattern=Pattern.compile("[0-9]*+((\\.[0-9]{0,"+ aiMinorUnits + "})?)||(\\.)?");

    } // InputFilterCurrency

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String lsStart  = "";
        String lsInsert = "";
        String lsEnd    = "";
        String lsText   = "";

        Log.d("debug", moPattern.toString());
        Log.d("debug", "source: " + source + ", start: " + start + ", end:" + end + ", dest: " + dest + ", dstart: " + dstart + ", dend: " + dend );

        lsText = dest.toString();

        // If the length is greater then 0, then insert the new character
        // into the original text for validation
        if (lsText.length() > 0) {

            lsStart = lsText.substring(0, dstart);
            Log.d("debug", "lsStart : " + lsStart);
            // Check to see if they have deleted a character
            if (source != "") {
                lsInsert = source.toString();
                Log.d("debug", "lsInsert: " + lsInsert);
            } // if
            lsEnd = lsText.substring(dend);
            Log.d("debug", "lsEnd   : " + lsEnd);
            lsText = lsStart + lsInsert + lsEnd;
            Log.d("debug", "lsText  : " + lsText);

        } // if

        Matcher loMatcher = moPattern.matcher(lsText);
        Log.d("debug", "loMatcher.matches(): " + loMatcher.matches() + ", lsText: " + lsText);
        if(!loMatcher.matches()) {
            return "";
        }
        return null;

    } // CharSequence

} // InputFilterCurrency
Run Code Online (Sandbox Code Playgroud)

以及设置 editText 过滤器的调用

editText.setFilters(new InputFilter[] {new InputFilterCurrency(2)});

Ouput with two decimal places
05-22 15:25:33.434: D/debug(30524): [0-9]*+((\.[0-9]{0,2})?)||(\.)?
05-22 15:25:33.434: D/debug(30524): source: 5, start: 0, end:1, dest: 123.4, dstart: 5, dend: 5
05-22 15:25:33.434: D/debug(30524): lsStart : 123.4
05-22 15:25:33.434: D/debug(30524): lsInsert: 5
05-22 15:25:33.434: D/debug(30524): lsEnd   : 
05-22 15:25:33.434: D/debug(30524): lsText  : 123.45
05-22 15:25:33.434: D/debug(30524): loMatcher.matches(): true, lsText: 123.45

Ouput inserting a 5 in the middle
05-22 15:26:17.624: D/debug(30524): [0-9]*+((\.[0-9]{0,2})?)||(\.)?
05-22 15:26:17.624: D/debug(30524): source: 5, start: 0, end:1, dest: 123.45, dstart: 2, dend: 2
05-22 15:26:17.624: D/debug(30524): lsStart : 12
05-22 15:26:17.624: D/debug(30524): lsInsert: 5
05-22 15:26:17.624: D/debug(30524): lsEnd   : 3.45
05-22 15:26:17.624: D/debug(30524): lsText  : 1253.45
05-22 15:26:17.624: D/debug(30524): loMatcher.matches(): true, lsText: 1253.45
Run Code Online (Sandbox Code Playgroud)


小智 5

我改进了 Pinhassi 使用正则表达式的解决方案,因此它也可以正确处理边缘情况。在检查输入是否正确之前,首先按照 android 文档的描述构造最终字符串。

public class DecimalDigitsInputFilter implements InputFilter {

    private Pattern mPattern;

    private static final Pattern mFormatPattern = Pattern.compile("\\d+\\.\\d+");

    public DecimalDigitsInputFilter(int digitsBeforeDecimal, int digitsAfterDecimal) {
        mPattern = Pattern.compile(
            "^\\d{0," + digitsBeforeDecimal + "}([\\.,](\\d{0," + digitsAfterDecimal +
                "})?)?$");
    }

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

        String newString =
            dest.toString().substring(0, dstart) + source.toString().substring(start, end) 
            + dest.toString().substring(dend, dest.toString().length());

        Matcher matcher = mPattern.matcher(newString);
        if (!matcher.matches()) {
            return "";
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});
Run Code Online (Sandbox Code Playgroud)


koa*_*a73 5

我已经更改了答案 \xe2\x84\x966 (由 Favas Kv ),因为你可以将点放在第一个位置。

\n\n
final InputFilter [] filter = { new InputFilter() {\n\n    @Override\n    public CharSequence filter(CharSequence source, int start, int end,\n                               Spanned dest, int dstart, int dend) {\n        StringBuilder builder = new StringBuilder(dest);\n        builder.replace(dstart, dend, source\n                .subSequence(start, end).toString());\n        if (!builder.toString().matches(\n                "(([1-9]{1})([0-9]{0,4})?(\\\\.)?)?([0-9]{0,2})?"\n\n        )) {\n            if(source.length()==0)\n                return dest.subSequence(dstart, dend);\n            return "";\n        }\n        return null;\n    }\n}};\n
Run Code Online (Sandbox Code Playgroud)\n