业务背景
公司的产品是一款金融类APP,在用户输入金额时需要限定用户输入的整数位数以及小数位数。比如,限制用户最多能输入6位整数,4位小数。
思路分析
如果输入的内容以
.
开头,自动在首位插入一个0
;如果首位是
0
,且其后为数字,否则删除首位的0
;如果整数部分或小数部分已达到限制,则掐头去尾。
实现代码
在res/values/attrs.xml
中添加自定义属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DigitEditText">
<attr name="maxInteger" format="integer" />
<attr name="maxDecimal" format="integer" />
</declare-styleable>
</resources>
自定义EditText监听器限制输入规则
/**
* 支持通过自定义属性配置最多输入的整数和小数位数
* <p>
* maxInteger:最多输入的整数位数
* maxDecimal:最多输入的小数位数
* <p>
* create by haoxueren on 2020/3/4
*/
public class DigitEditText extends AppCompatEditText implements TextWatcher {
private int position = 0; // 超出当前限定的位数,删除新输入的数字
private AttributeHolder holder;
public DigitEditText(Context context) {
this(context, null);
}
public DigitEditText(Context context, AttributeSet attrs) {
super(context, attrs);
holder = new AttributeHolder(context, attrs);
this.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
this.addTextChangedListener(this);
}
public void setMaxInteger(int maxInteger) {
holder.setMaxInteger(maxInteger);
}
public void setMaxDecimal(int maxDecimal) {
holder.setMaxDecimal(maxDecimal);
}
/**
* 限制EditText输入,最多位整数,小数
*/
@Override
public void afterTextChanged(Editable editable) {
String text = editable.toString();
// 小数点前自动补0
if (text.matches("[.]\\d*")) {
editable.insert(0, "0");
return;
}
// 删除数字前的0(逐位删除)
if (text.matches("0[0-9][0-9.]*")) {
editable.delete(0, 1);
return;
}
// 最多输入6位整数(逐位删除)
if (text.matches(holder.integerRegex)) {
editable.delete(0, 1);
return;
}
// 最多输入4位小数(逐位删除)
if (text.matches(holder.decimalRegex)) {
int last = this.length();
editable.delete(last-1, last);
return;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
this.position = start;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
class AttributeHolder {
private String integerRegex;
private String decimalRegex;
AttributeHolder(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DigitEditText);
// 整数最大位数,默认为10
int maxInteger = typedArray.getInt(R.styleable.DigitEditText_maxInteger, 10);
// 小数最大位数,默认为10
int maxDecimal = typedArray.getInt(R.styleable.DigitEditText_maxDecimal, 10);
integerRegex = String.format(Locale.CHINA, "\\d{%d,}[0-9.]*", maxInteger + 1);
decimalRegex = String.format(Locale.CHINA, "\\d+[.]\\d{%d,}", maxDecimal + 1);
typedArray.recycle();
}
private void setMaxInteger(int maxInteger) {
integerRegex = String.format(Locale.CHINA, "\\d{%d,}[0-9.]*", maxInteger + 1);
}
private void setMaxDecimal(int maxDecimal) {
decimalRegex = String.format(Locale.CHINA, "\\d+[.]\\d{%d,}", maxDecimal + 1);
}
}
}
使用方法
<com.haoxueren.library.view.DigitEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:maxDecimal="4"
app:maxInteger="6" />