EditText是Android中一個(gè)常用的控件,有很多InputType,可以來(lái)達(dá)到不同的輸入效果。比如,密碼輸入,數(shù)字輸入,電話號(hào)碼輸入等等,但是如果要實(shí)現(xiàn)EditText輸入金額,金額的限制因素很多,比如,只能輸入數(shù)字和小數(shù)點(diǎn),首位不能輸入0和小數(shù)點(diǎn),小數(shù)點(diǎn)后面只能保留兩位等等,這些僅僅用InputType是無(wú)法實(shí)現(xiàn)的,我們需要同時(shí)借助inputType和InputFilter來(lái)實(shí)現(xiàn)。
效果圖

edittext 金額.jpg
分析
既然inputtype不能完全滿足我們的需求,我們只能尋找別的辦法了。edittext有一個(gè)方法 setFilters(InputFilter[] filters);它的源碼如下
/**
* Sets the list of input filters that will be used if the buffer is
* Editable. Has no effect otherwise.
*
* @attr ref android.R.styleable#TextView_maxLength
*/
public void setFilters(InputFilter[] filters) {
if (filters == null) {
throw new IllegalArgumentException();
}
mFilters = filters;
if (mText instanceof Editable) {
setFilters((Editable) mText, filters);
}
}
大致意思是說(shuō),InputFilter的作用是對(duì)輸入的文字進(jìn)行過(guò)濾,可以自定義處理,這句話的意思是可以設(shè)置自定義處理對(duì)象列表,但是他們是否會(huì)起作用還要看TextView的文字緩沖區(qū)是否是Editable。
關(guān)于InputFilter ,大家可以參考如下文章
TextView和EditText中的setFilters方法說(shuō)明
實(shí)現(xiàn)
- 首先需要將EditText的InputType設(shè)置成如下格式,保證用戶只能輸入小數(shù)點(diǎn)和數(shù)字
android:inputType="numberDecimal"
//或者
setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL)
- 自定義一個(gè)類(lèi)實(shí)現(xiàn)InputFilter接口,代碼如下:
CashierInputFilter.java
/**
* 過(guò)濾用戶輸入只能為金額格式
*
* 作者: 周旭 on 2017年9月14日 0014.
* 郵箱:374952705@qq.com
* 博客:http://www.itdecent.cn/u/56db5d78044d
*/
public class CashierInputFilter implements InputFilter {
Pattern mPattern;
//輸入的最大金額
private static final int MAX_VALUE = Integer.MAX_VALUE;
//小數(shù)點(diǎn)后的位數(shù)
private static final int POINTER_LENGTH = 2;
private static final String POINTER = ".";
private static final String ZERO = "0";
public CashierInputFilter() {
mPattern = Pattern.compile("([0-9]|\\.)*");
}
/**
* @param source 新輸入的字符串
* @param start 新輸入的字符串起始下標(biāo),一般為0
* @param end 新輸入的字符串終點(diǎn)下標(biāo),一般為source長(zhǎng)度-1
* @param dest 輸入之前文本框內(nèi)容
* @param dstart 原內(nèi)容起始坐標(biāo),一般為0
* @param dend 原內(nèi)容終點(diǎn)坐標(biāo),一般為dest長(zhǎng)度-1
* @return 輸入內(nèi)容
*/
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
String sourceText = source.toString();
String destText = dest.toString();
//驗(yàn)證刪除等按鍵
if (TextUtils.isEmpty(sourceText)) {
return "";
}
Matcher matcher = mPattern.matcher(source);
//已經(jīng)輸入小數(shù)點(diǎn)的情況下,只能輸入數(shù)字
if(destText.contains(POINTER)) {
if (!matcher.matches()) {
return "";
} else {
if (POINTER.equals(source.toString())) { //只能輸入一個(gè)小數(shù)點(diǎn)
return "";
}
}
//驗(yàn)證小數(shù)點(diǎn)精度,保證小數(shù)點(diǎn)后只能輸入兩位
int index = destText.indexOf(POINTER);
int length = dend - index;
if (length > POINTER_LENGTH) {
return dest.subSequence(dstart, dend);
}
} else {
/**
* 沒(méi)有輸入小數(shù)點(diǎn)的情況下,只能輸入小數(shù)點(diǎn)和數(shù)字
* 1. 首位不能輸入小數(shù)點(diǎn)
* 2. 如果首位輸入0,則接下來(lái)只能輸入小數(shù)點(diǎn)了
*/
if (!matcher.matches()) {
return "";
} else {
if ((POINTER.equals(source.toString())) && TextUtils.isEmpty(destText)) { //首位不能輸入小數(shù)點(diǎn)
return "";
} else if (!POINTER.equals(source.toString()) && ZERO.equals(destText)) { //如果首位輸入0,接下來(lái)只能輸入小數(shù)點(diǎn)
return "";
}
}
}
//驗(yàn)證輸入金額的大小
double sumText = Double.parseDouble(destText + sourceText);
if (sumText > MAX_VALUE) {
return dest.subSequence(dstart, dend);
}
return dest.subSequence(dstart, dend) + sourceText;
}
}
3.edittext的調(diào)用
InputFilter[] filters={new CashierInputFilter()};
refundMoneyEdt.setFilters(filters); //設(shè)置金額輸入的過(guò)濾器,保證只能輸入金額類(lèi)型