Android開發之EditText字符串過濾器InputFilter

Android開發值EditText字符串過濾器InputFilter

本文轉載自 talentclass_ctt 的 Android開發值EditText字符串過濾器InputFilter

一、InputFilter 是什麼?有什麼用?

在Android編程中,一般沒什麼特殊要求的話,我們用EditText可能只會用到xml裏面的限制輸入類型、最大長度,行數等等這些簡單的控制,但如果我們想要進行一些複雜一點的輸入控制(比如:限制單字節多少位,雙字節多少位;限制只能輸入業務要求的特定的字符;修改輸入字符)就要用今天要講的InputFilter了。

二、怎麼用?

1、創建一個類去implements InputFilter,實現filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)方法;
2、在要用到的地方調用EditText的setFilters(InputFilter[] filters)方法即可。
例子(限制雙字節字符16位,單字節字符32位):
NameFilter.java

public class NameFilter implements InputFilter {
 
    private int mMaxLen = 16;
 
    public NameFilter() {
    }
 
    public NameFilter(int maxLen) {
        this.mMaxLen = maxLen;
    }
 
    @Override
    public CharSequence filter(CharSequence source, 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 < source.length()) {
            char c = source.charAt(sindex++);
            if (c < 128) {
                count = count + 1;
            } else {
                count = count + 2;
            }
        }
 
        if (count > mMaxLen) {
            sindex--;
        }
        return source.subSequence(0, sindex);
    }
}

在要用到的地方加上:

// 表示單字節字符最長16位,雙字節字符最長8位;根據業務傳值
mEtName.setFilters(new InputFilter[]{new NameFilter(16)});

三、更多

LoginFilter實現了InputFilter接口,而它的構造函數是不公開的,所以我們可以通過重寫LoginFilter的子類的isAllowed方法,達到代碼過濾EditText字符串的目的。

public abstract class LoginFilter implements InputFilter {
    LoginFilter() {
        throw new RuntimeException("Stub!");
    }
 
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        throw new RuntimeException("Stub!");
    }
 
    public void onStart() {
        throw new RuntimeException("Stub!");
    }
 
    public void onInvalidCharacter(char c) {
        throw new RuntimeException("Stub!");
    }
 
    public void onStop() {
        throw new RuntimeException("Stub!");
    }
 
    public abstract boolean isAllowed(char var1);
 
    public static class PasswordFilterGMail extends LoginFilter {
        public PasswordFilterGMail() {
            throw new RuntimeException("Stub!");
        }
 
        public PasswordFilterGMail(boolean appendInvalid) {
            throw new RuntimeException("Stub!");
        }
 
        public boolean isAllowed(char c) {
            throw new RuntimeException("Stub!");
        }
    }
 
    public static class UsernameFilterGeneric extends LoginFilter {
        public UsernameFilterGeneric() {
            throw new RuntimeException("Stub!");
        }
 
        public UsernameFilterGeneric(boolean appendInvalid) {
            throw new RuntimeException("Stub!");
        }
 
        public boolean isAllowed(char c) {
            throw new RuntimeException("Stub!");
        }
    }
 
    public static class UsernameFilterGMail extends LoginFilter {
        public UsernameFilterGMail() {
            throw new RuntimeException("Stub!");
        }
 
        public UsernameFilterGMail(boolean appendInvalid) {
            throw new RuntimeException("Stub!");
        }
 
        public boolean isAllowed(char c) {
            throw new RuntimeException("Stub!");
        }
    }
}

可以看到繼承LoginFilter的有PasswordFilterGMail、UsernameFilterGeneric、UsernameFilterGMail,我們無法繼承LoginFilter,但是可以繼承這三個類。
例子(限制只能輸入數字和英文):

public class MyLoginFilter extends LoginFilter.UsernameFilterGMail {
    public  MyLoginFilter() {
        super();
    }
 
    @Override
    public boolean isAllowed(char c) {
        if ('0' <= c && c <= '9')
            return true;
        if ('a' <= c && c <= 'z')
            return true;
        if ('A' <= c && c <= 'Z')
            return true;
        return false;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章