Android中EditText字串過濾器InputFilter
阿新 • • 發佈:2018-11-03
作用
Android中的Edittext使用時,如果我們要進行一些複雜的輸入控制(比如:限制單位元組多少位;限制只能輸入業務要求的特定的字元等)就要用InputFilter了
用法
1、建立一個類去implements InputFilter,實現filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)方法
2、在要用到的地方呼叫EditText的setFilters(InputFilter[] filters)方法
public abstract CharSequence filter ( CharSequence source, //輸入的文字 ,即將輸入的字串 int start, //開始位置 ,source的start int end, //結束位置 ,source的end,或理解為長度 Spanned dest, //當前顯示的內容 ,輸入框中原來的內容 int dstart, //當前開始位置,要替換或者新增的起始位置,即游標所在的位置 int dend //當前的結束位置,要替換或者新增的終止始位置,若為選擇一串字串進行更改,則為選中字串 最後一個字元在dest中的位置 );
栗子:名稱輸入長度限制
import android.text.InputFilter; import android.text.Spanned; public class NameInputFilter implements InputFilter { private int mMaxLen = 16; public NameInputFilter() { } public NameInputFilter(int maxLen) { this.mMaxLen = maxLen; } @Override public CharSequence filter(CharSequence charSequence, int start, int end, Spanned dest, int dstart, int dend) { int dindex = 0; int count = 0; // 判斷是否到達最大長度 while (count <= mMaxLen && dindex < dest.length()) { char c = dest.charAt(dindex++); if (c < 128) {// 按ASCII碼錶0-127算 count = count + 1; } else { count = count + 2; } } if (count > mMaxLen) { return dest.subSequence(0, dindex - 1); } int sindex = 0; while (count <= mMaxLen && sindex < charSequence.length()) { char c = charSequence.charAt(sindex++); if (c < 128) { count = count + 1; } else { count = count + 2; } } if (count > mMaxLen) { sindex--; } return charSequence.subSequence(0, sindex); } }
用法
editText.setFilters(new NameInputFilter[]{new NameInputFilter(8)});// 表示單位元組字元最長8位,雙位元組字元最長4位;根據業務傳值
栗子:數字最多輸入小數點後兩位
/** *金額輸入過濾器,限制小數點後輸入位數 * * 預設限制小數點2位 * 預設第一位輸入小數點時,轉換為0. * 如果起始位置為0,且第二位跟的不是".",則無法後續輸入 */ public class MoneyValueFilter extends DigitsKeyListener { private static final String TAG = "MoneyValueFilter"; public MoneyValueFilter() { super(false, true); } private int digits = 2; public MoneyValueFilter setDigits(int d) { digits = d; return this; } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { CharSequence out = super.filter(source, start, end, dest, dstart, dend); Log.d(TAG, "-------source:"+source); Log.d(TAG, "-------start:"+start); Log.d(TAG, "-------end:"+end); Log.d(TAG, "-------dest:"+dest); Log.d(TAG, "-------dstart:"+dstart); Log.d(TAG, "-------dend:"+dend); // if changed, replace the source if (out != null) { source = out; start = 0; end = out.length(); } int len = end - start; // if deleting, source is empty // and deleting can't break anything if (len == 0) { return source; } //以點開始的時候,自動在前面新增0 if(source.toString().equals(".") && dstart == 0){ return "0."; } //如果起始位置為0,且第二位跟的不是".",則無法後續輸入 if(!source.toString().equals(".") && dest.toString().equals("0")){ return ""; } int dlen = dest.length(); // Find the position of the decimal . for (int i = 0; i < dstart; i++) { if (dest.charAt(i) == '.') { // being here means, that a number has // been inserted after the dot // check if the amount of digits is right return (dlen-(i+1) + len > digits) ? "" : new SpannableStringBuilder(source, start, end); } } for (int i = start; i < end; ++i) { if (source.charAt(i) == '.') { // being here means, dot has been inserted // check if the amount of digits is right if ((dlen-dend) + (end-(i + 1)) > digits) return ""; else break; // return new SpannableStringBuilder(source, start, end); } } Log.d(TAG, "-------return:"+new SpannableStringBuilder(source, start, end).toString()); Log.d(TAG, "-----------------------"); // if the dot is after the inserted part, // nothing can break return new SpannableStringBuilder(source, start, end); } }
用法
xml
<EditText
android:id="@+id/et_inputFilter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
程式碼中
editText.setFilters(new InputFilter[]{new MoneyValueFilter().setDigits(2)});