我有一个EditText
框,必须允许用户输入最多7个数字和两个小数位。输入七位数后,不应再允许添加一位数,但我可能允许最多2位小数。我使用十进制过滤器为2位小数,这个代码用XML
android:maxLength="7"
android:imeOptions="actionDone"
android:inputType="numberDecimal"
但EditText
允许enter
8位数。怎么解决这个问题?
答案 0 :(得分:23)
在onCreate
下试试 youreditText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,1)});
在您的计划中的任何位置
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;
}
}
答案 1 :(得分:6)
您可以使用此输入过滤器来解决您的问题。 设置过滤器:
mEditText.setFilters(new InputFilter[]{new DigitsInputFilter(maxDigitsBeforeDot, maxDigitsAfterDot, maxValue)});
如果不希望限制点之前或之后的数字,只需将Integer.MAX_VALUE
添加到禁用最大值限制,请使用Double.POSITIVE_INFINITY
。
您可以将此过滤器用于输入数字或数字和文本的文本字段。
public class DigitsInputFilter implements InputFilter {
private final String DOT = ".";
private int mMaxIntegerDigitsLength;
private int mMaxDigitsAfterLength;
private double mMax;
public DigitsInputFilter(int maxDigitsBeforeDot, int maxDigitsAfterDot, double maxValue) {
mMaxIntegerDigitsLength = maxDigitsBeforeDot;
mMaxDigitsAfterLength = maxDigitsAfterDot;
mMax = maxValue;
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String allText = getAllText(source, dest, dstart);
String onlyDigitsText = getOnlyDigitsPart(allText);
if (allText.isEmpty()) {
return null;
} else {
double enteredValue;
try {
enteredValue = Double.parseDouble(onlyDigitsText);
} catch (NumberFormatException e) {
return "";
}
return checkMaxValueRule(enteredValue, onlyDigitsText);
}
}
private CharSequence checkMaxValueRule(double enteredValue, String onlyDigitsText) {
if (enteredValue > mMax) {
return "";
} else {
return handleInputRules(onlyDigitsText);
}
}
private CharSequence handleInputRules(String onlyDigitsText) {
if (isDecimalDigit(onlyDigitsText)) {
return checkRuleForDecimalDigits(onlyDigitsText);
} else {
return checkRuleForIntegerDigits(onlyDigitsText.length());
}
}
private boolean isDecimalDigit(String onlyDigitsText) {
return onlyDigitsText.contains(DOT);
}
private CharSequence checkRuleForDecimalDigits(String onlyDigitsPart) {
String afterDotPart = onlyDigitsPart.substring(onlyDigitsPart.indexOf(DOT), onlyDigitsPart.length() - 1);
if (afterDotPart.length() > mMaxDigitsAfterLength) {
return "";
}
return null;
}
private CharSequence checkRuleForIntegerDigits(int allTextLength) {
if (allTextLength > mMaxIntegerDigitsLength) {
return "";
}
return null;
}
private String getOnlyDigitsPart(String text) {
return text.replaceAll("[^0-9?!\\.]", "");
}
private String getAllText(CharSequence source, Spanned dest, int dstart) {
String allText = "";
if (!dest.toString().isEmpty()) {
if (source.toString().isEmpty()) {
allText = deleteCharAtIndex(dest, dstart);
} else {
allText = new StringBuilder(dest).insert(dstart, source).toString();
}
}
return allText;
}
private String deleteCharAtIndex(Spanned dest, int dstart) {
StringBuilder builder = new StringBuilder(dest);
builder.deleteCharAt(dstart);
return builder.toString();
}
}
我希望它可以帮到你。
答案 2 :(得分:4)
edittext.setFilters(new InputFilter[] { new DigitsKeyListener(
Boolean.FALSE, Boolean.TRUE) {
int beforeDecimal = 7, afterDecimal = 2;
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
String etText = edittext.getText().toString();
if (etText.isEmpty()){
return null;
}
String temp = edittext.getText() + source.toString();
if (temp.equals(".")) {
return "0.";
} else if (temp.toString().indexOf(".") == -1) {
// no decimal point placed yet
if (temp.length() > beforeDecimal) {
return "";
}
} else {
int dotPosition ;
int cursorPositon = edittext.getSelectionStart();
if (etText.indexOf(".") == -1) {
Log.i("First time Dot", etText.toString().indexOf(".")+" "+etText);
dotPosition = temp.indexOf(".");
Log.i("dot Positon", cursorPositon+"");
Log.i("dot Positon", etText+"");
Log.i("dot Positon", dotPosition+"");
}else{
dotPosition = etText.indexOf(".");
Log.i("dot Positon", cursorPositon+"");
Log.i("dot Positon", etText+"");
Log.i("dot Positon", dotPosition+"");
}
if(cursorPositon <= dotPosition){
Log.i("cursor position", "in left");
String beforeDot = etText.substring(0, dotPosition);
if(beforeDot.length()<beforeDecimal){
return source;
}else{
if(source.toString().equalsIgnoreCase(".")){
return source;
}else{
return "";
}
}
}else{
Log.i("cursor position", "in right");
temp = temp.substring(temp.indexOf(".") + 1);
if (temp.length() > afterDecimal) {
return "";
}
}
}
return super.filter(source, start, end, dest, dstart, dend);
}
} });
答案 3 :(得分:2)
您可以使用此输入过滤器来解决您的问题。要设置过滤器: 对于4位数和2个小数点
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) {
String s = Html.toHtml(dest).replaceAll("\\<.*?>","").replaceAll("\n","");
Matcher matcher = mPattern.matcher(dest);
if (!matcher.matches())
return "";
try {
if(Double.parseDouble(s)<9999.99 && s.contains(".")) {
return null;
}else if ((Double.parseDouble(s)<1000 && !s.contains("."))||source.equals(".")) {
return null;
}else {
return "";
}
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
editText.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(7, 2)});
答案 4 :(得分:0)
虽然不是直接解决方案,但您可以通过TextWatcher
关于如何使用TextWatcher
的SO Q&amp; A之一是here
有关TextWatcher
的更多信息,请here
您可能需要Regular expression to match floating point precision&amp;的帮助。 pattern matcher 验证输入。
答案 5 :(得分:0)
使用Android数据绑定时可以增强它:
定义自定义绑定适配器:
@BindingAdapter({"digitsBeforeZero", "digitsAfterZero"})
public void bindAmountInputFilter(EditText view, int digitsBeforeZero, int digitsAfterZero) {
view.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(digitsBeforeZero, digitsAfterZero)});
}
向EditText添加属性:
app:digitsBeforeZero="@{7}"
app:digitsAfterZero="@{2}"
它会自动设置edittext的输入过滤器
答案 6 :(得分:0)
首先在onCreate中创建此
DecimalFormat amountFormate = new DecimalFormat("#######.##");
amountFormate.setMinimumFractionDigits(2);
amountFormate.setMaximumFractionDigits(2);
editText.setText(amountFormate.format(yourValue));
示例:
double amount = 1234567.54;
editText.setText(amountFormate.format(amount));
输出-> 1234567.54