Blog
Blog copied to clipboard
两种方法限制 EditText 最多输入两位小数
版权声明:本文为 Bakumon 原创文章,转载需在明确位置注明出处!!!https://github.com/Bakumon/blog/issues/10
测试又提 EditText 输入限制的 bug 🐛 了,这次是和小数点有关的。
bug:需要限制 EditText 最多输入两位小数。
🤕
事情是这样的,app 中新增信息中有一栏需要输入投资额,单位是万元,对于这种 EditText 我想都不用想直接用小数键盘就 OK 啊。
android:inputType="numberDecimal"
可是问题来了,测试输入了一个特别大的数,类似于 123456789987654321 ,接口直接报了 400 (客户端错误),说明客户端提交的参数不符合服务器设定的参数类型。
WTF! 这显然不是 App 的 bug 啊! “去找后台吧”,又一次给了测试这个感人的建议。
出现转折了,后台说他解决不了,[黑人问号脸].jpg
后来测试说限制一下输入的位数就行,因为 9 位以下是没问题的,虽然不是解决问题的方法,但是没办法,谁让后台不给力呢,于是出现了这个 EditText 只能输入 9 位的小数数字。
android:maxLength="9"
以上纯属扯蛋,请自行忽略。
后来客户提出要求,这个输入框限制最多输入两位小数吧。于是就有了文章开头的 bug 🐛 。
细节要求:
- 以小数点开头,前面自动加上 "0"
- 以小数点结尾,去掉小数点
下面有两种方法分别实现:
一、添加 TextChangedListener 输入监听
思路:利用 EditText 的输入监听实现小数位的截取,和移动光标到末尾,在失去焦点后,去掉结尾的小数点。
添加输入监听:
editText.addTextChangedListener(new TextWatcher() {
boolean deleteLastChar;// 是否需要删除末尾
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().contains(".")) {
// 如果点后面有超过三位数值,则删掉最后一位
int length = s.length() - s.toString().lastIndexOf(".");
// 说明后面有三位数值
deleteLastChar = length >= 4;
}
}
@Override
public void afterTextChanged(Editable s) {
if (s == null) {
return;
}
if (deleteLastChar) {
// 设置新的截取的字符串
editText.setText(s.toString().substring(0, s.toString().length() - 1));
// 光标强制到末尾
editText.setSelection(editText.getText().length());
}
// 以小数点开头,前面自动加上 "0"
if (s.toString().startsWith(".")) {
editText.setText("0" + s);
editText.setSelection(editText.getText().length());
}
}
});
添加失去焦点监听:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
EditText editText1 = (EditText) v;
// 以小数点结尾,去掉小数点
if (!hasFocus && editText1.getText() != null && editText1.getText().toString().endsWith(".")) {
editText.setText(editText1.getText().subSequence(0, editText1.getText().length() - 1));
editText.setSelection(editText.getText().length());
}
}
});
封装在了一个单例类中,点击下面链接查看完整代码: 代码Gist (Gist需科学上网)
二、设置 InputFiler
这确实不是后台的问题