前言
在一些只需要数字输入的地方,经常会使用数字范围来限制输入的数字。具体可参考我这篇文章:android EditText输入框限制输入数字大小,一个页面内多次调整范围
用这个方法,一直在各个项目中复制粘贴,如鱼得水。
可是,有一天,我遇到了个需求是
限制输入数值【10~80】
直接复制筛选方法进去,结果表现出来就是只能是10或者80.。。。
为什么呢?
因为,里面的方法只有两句判断逻辑,当输入的字符串转换成数字小于最小值,就变成最小值,当输入的字符串转换成数字大于最大值,就变成最大值。
而当范围是10~80的时候,输入任何各位数都会马上变成10,再输入一位数变成3位数,马上变成80了。。。
这就很蛋疼了
解决
尝试了好久,终于解决了,具体看代码:
/**
* 设定输入框输入数字范围
* @param editText
* @param min
* @param max
*/
private void setEditTextRange(final EditText editText, final int min, final int max) {
TextWatcher watcher = mEdtWatcherMap.get(editText);
if (null != watcher) {
editText.removeTextChangedListener(watcher);
}
watcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
LogUtils.errorLog("beforeTextChanged", "s=" + s.toString()
+ "; start=" + start + "; count=" + count + "; after=" + after);
}
@SuppressLint("SetTextI18n")
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
LogUtils.errorLog("onTextChanged", "s=" + s.toString()
+ "; start=" + start + "; before=" + before + "; count=" + count);
// 拿到数字
if (s.toString().isEmpty()) {
setTextInEditText(editText, min);
return;
}
int value = Integer.valueOf(s.toString());
if (s.toString().substring(0, 1).contains("0") && value != 0) {
// 第一个字为0
setTextInEditText(editText, value);
return;
}
// 判断大小
if (value < min) {
setTextInEditText(editText, min);
} else if (value > max) {
// 移除最老的第一个数试试看
String ads = s.toString().substring(1);
if (ads.isEmpty()) ads = "0";
int ad = Integer.parseInt(ads);
if (ad >= min && ad <= max) {
setTextInEditText(editText, ad);
} else {
// 排除输入的最后一个是0
String ssr = s.toString().substring(0, s.toString().length() -1);
if (ssr.contains("0")) {
// 移除最老的0
ssr = s.toString().substring(0, s.toString().indexOf("0"))
+ s.toString().substring(s.toString().indexOf("0") + 1);
value = Integer.valueOf(ssr);
if (value >= min && value <= max) {
setTextInEditText(editText, value);
return;
}
}
setTextInEditText(editText, max);
}
}
}
@SuppressLint("SetTextI18n")
@Override
public void afterTextChanged(Editable s) {
LogUtils.errorLog("afterTextChanged", "s=" + s.toString());
}
};
editText.addTextChangedListener(watcher);
mEdtWatcherMap.put(editText, watcher);
}
逻辑
- 拿到当前字符串,如果是空的,填入最小值。结束。
- 如果字符串的第一个数值是0,那就删掉这个0 。结束。
- 如果当前字符串转换的数值小于最小值,那就填入最小值。结束。
- 如果当前字符串转换的数值大于最大值,先尝试删除第一个数字,肯定是非0的。如果结果不在范围内。那就肯定是存在0,使得数小了一位。那就去删掉第一个0,如果结果还是大于范围,那就直接填入最大范围。