您知道有哪些方法可以确保用户只能输入最大小数位数的数字。
我不知道如何解决这个问题。在MS SQL数据库中,我将从我的应用程序发送数据我有这种类型的列decimal(8,3)
现在考虑最终要存储我想在Android中验证的值的列的数据类型,我考虑过这两种情况:
现在我确定第一种情况,但不是第二种情况。 保持最大位数固定是否正确(例如,始终为8)?或者我应该考虑允许小数点左边最多8位数,小数点右边3点?
无论哪种方式,这都是我在Android中尝试过的方法:
mQuantityEditText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
String str = mQuantityEditText.getText().toString();
DecimalFormat format = (DecimalFormat) DecimalFormat
.getInstance();
DecimalFormatSymbols symbols = format.getDecimalFormatSymbols();
char sep = symbols.getDecimalSeparator();
int indexOFdec = str.indexOf(sep);
if (indexOFdec >= 0) {
if (str.substring(indexOFdec, str.length() - 1).length() > 3) {
s.replace(0, s.length(),
str.substring(0, str.length() - 1));
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
});
尽管如此,上面的代码处理了最大小数位数。它不限制EditText中允许的总位数。
您认为可以帮助我改进代码,以便它处理最大小数位数和EditText中允许的总位数(考虑小数点左侧和右侧的数字)
好吧,现在我正在尝试JoãoSousa建议的内容,这就是我尝试过的内容:
1)我定义了一个实现InputFilter
的类public class NumberInputFilter implements InputFilter {
private Pattern mPattern;
public NumberInputFilter(int precision, int scale) {
String pattern="^\\-?(\\d{0," + (precision-scale) + "}|\\d{0," + (precision-scale) + "}\\.\\d{0," + scale + "})$";
this.mPattern=Pattern.compile(pattern);
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned destination, int destinationStart, int destinationEnd) {
if (end > start) {
// adding: filter
// build the resulting text
String destinationString = destination.toString();
String resultingTxt = destinationString.substring(0, destinationStart) + source.subSequence(start, end) + destinationString.substring(destinationEnd);
// return null to accept the input or empty to reject it
return resultingTxt.matches(this.mPattern.toString()) ? null : "";
}
// removing: always accept
return null;
}
}
2)试图使用这样的类:
mQuantityEditText.setFilters(new InputFilter[] { new NumberInputFilter(8,3)} );
答案 0 :(得分:9)
我会使用正则表达式的力量在编辑文本中寻找过滤器。首先是正则表达式:
^\-?(\d{0,5}|\d{0,5}\.\d{0,3})$
也许有多种方法可以改善这种表达方式,但这确实很有用。
现在只需在edittext中设置输入过滤器,如下所示:
final String regex = "^\-?(\d{0,5}|\d{0,5}\.\d{0,3})$";
((EditText)rootView.findViewById(R.id.editText1)).setFilters(new InputFilter[] {
new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned destination, int destinationStart, int destinationEnd) {
if (end > start) {
// adding: filter
// build the resulting text
String destinationString = destination.toString();
String resultingTxt = destinationString.substring(0, destinationStart) + source.subSequence(start, end) + destinationString.substring(destinationEnd);
// return null to accept the input or empty to reject it
return resultingTxt.matches(regex) ? null : "";
}
// removing: always accept
return null;
}
}
});
顺便说一句,我刚测试了这段代码,它的作用是:
我是否正确理解了您描述的问题?
- 编辑
好的,我差不多了。根据我的理解,十进制(8,3)表示最多8位数字,包括小数点左侧或右侧的数字,范围从-99999.999
到99999.999
。
至少这是我从这句话Standard SQL requires that DECIMAL(5,2) be able to store any value with five digits and two decimals, so values that can be stored in the salary column range from -999.99 to 999.99
中理解的内容。即使它来自MySQL文档,MSSQL文档似乎也是如此。
答案 1 :(得分:1)
我为你回答,在这种情况下我也遭受了很多痛苦。:D:P
我已经实现了这一点,左边最多4位,小数点右边2点:4444.99
这么小的变化需要实现我所做的: 需要做以下更改
1)复制CustomTextWatcher.java以跟踪editText的输入。
import java.text.NumberFormat;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
public class CustomTextWatcher implements TextWatcher {
private NumberFormat nf = NumberFormat.getNumberInstance();
private EditText et;
private String tmp = "";
private int moveCaretTo;
private static final int INTEGER_CONSTRAINT = 4;
private static final int FRACTION_CONSTRAINT = 2;
private static final int MAX_LENGTH = INTEGER_CONSTRAINT
+ FRACTION_CONSTRAINT + 1;
public CustomTextWatcher(EditText et) {
this.et = et;
nf.setMaximumIntegerDigits(INTEGER_CONSTRAINT);
nf.setMaximumFractionDigits(FRACTION_CONSTRAINT);
nf.setGroupingUsed(false);
}
public int countOccurrences(String str, char c) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == c) {
count++;
}
}
return count;
}
@Override
public void afterTextChanged(Editable s) {
et.removeTextChangedListener(this); // remove to prevent stackoverflow
String ss = s.toString();
int len = ss.length();
int dots = countOccurrences(ss, '.');
boolean shouldParse = dots <= 1
&& (dots == 0 ? len != (INTEGER_CONSTRAINT + 1)
: len < (MAX_LENGTH + 1));
if (shouldParse) {
if (len > 1 && ss.lastIndexOf(".") != len - 1) {
try {
if (ss.contains(".")) {
String[] integerFractionStrings = ss.split("\\.");
Log.v("Check SS ", ss);
Log.v("second string", "Found"
+ integerFractionStrings.length);
if (integerFractionStrings.length > 1) {
Log.v("integerFractionStrings",
integerFractionStrings[1]);
if (integerFractionStrings[1].length() == 1
&& integerFractionStrings[1].charAt(0) == '0') {
et.setText(ss);
Log.v("second string", "size 1");
} else {
Log.v("second string", "> 1");
Double d = Double.parseDouble(ss);
if (d != null) {
et.setText(nf.format(d));
}
}
}
} else {
Log.v("First string", "No dot");
Double d = Double.parseDouble(ss);
if (d != null) {
et.setText(nf.format(d));
}
}
} catch (NumberFormatException e) {
}
}
} else {
Log.v("second string", "size 1");
et.setText(tmp);
}
et.addTextChangedListener(this); // reset listener
// tried to fix caret positioning after key type:
if (et.getText().toString().length() > 0) {
if (dots == 0 && len >= INTEGER_CONSTRAINT
&& moveCaretTo > INTEGER_CONSTRAINT) {
moveCaretTo = INTEGER_CONSTRAINT;
} else if (dots > 0 && len >= (MAX_LENGTH)
&& moveCaretTo > (MAX_LENGTH)) {
moveCaretTo = MAX_LENGTH;
}
try {
et.setSelection(et.getText().toString().length());
// et.setSelection(moveCaretTo); <- almost had it :))
} catch (Exception e) {
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
moveCaretTo = et.getSelectionEnd();
tmp = s.toString();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int length = et.getText().toString().length();
if (length > 0) {
moveCaretTo = start + count - before;
}
}
}
2)设置此类以通过以下方式检查您的editText。
EditText review_food_Price;
review_food_Price = (EditText) findViewById(R.id.food_Price);
review_food_Price.setRawInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_FLAG_DECIMAL);
review_food_Price.addTextChangedListener(new CustomTextWatcher(
review_food_Price));
希望您可以根据需要转换我的代码。
答案 2 :(得分:0)
您描述的问题恰恰是Masked EditText的用途。 :)