在開發中,調試接口的時候,上傳了一段包含emoji的字符串,由於後臺沒有對emoji表情的編碼做處理,會導致接口不成功,這個時候我們就需要在前臺對數據做處理,那麼這個需求也就誕生了。說起emoji表情,網上有很多的禁止方法,有的是在edittext的字符改變時進行判斷,有的是自定義edittext,其實這兩種做法式一樣的,在字符改變的時候,對codeinput編碼進行正則判斷,大多數都採用的是區間形式的判斷,這裏有個誤區,當你去查閱emoji官方網站的時候,會發現其實在某些字符區間裏面,會包含一些漢字或者標點符號這些字符。因此單單通過區間來判斷是會出問題的,導致某些字符輸入不進去。
下面介紹一種方法,是給edittext添加過濾器,實現逐個對輸入字符進行過濾。
public class EmojiFilter implements InputFilter { private static Set<String> filterSet = null; private static Set<Scope> scopeSet = null; /** * 區間類模型 */ private class Scope { int start; int end; @Override public boolean equals(Object o) { if (o instanceof Scope) { Scope scope = (Scope) o; if (scope.start == start && scope.end == end) { return true; } } return super.equals(o); } } private static void addUnicodeRangeToSet(Set<String> set, int start, int end) { if (set == null) { return; } if (start > end) { return; } for (int i = start; i <= end; i++) { filterSet.add(new String(new int[]{i}, 0, 1)); } } private static void addUnicodeRangeToSet(Set<String> set, int code) { if (set == null) { return; } filterSet.add(new String(new int[]{code}, 0, 1)); } static { filterSet = new HashSet<String>(); scopeSet = new HashSet<>(); // See http://apps.timwhitlock.info/emoji/tables/unicode // 1. Emoticons ( 1F601 - 1F64F ) addUnicodeRangeToSet(filterSet, 0x1F601, 0X1F64F); // 2. Dingbats ( 2702 - 27B0 ) addUnicodeRangeToSet(filterSet, 0x2702, 0X27B0); // 3. Transport and map symbols ( 1F680 - 1F6C0 ) addUnicodeRangeToSet(filterSet, 0X1F680, 0X1F6C0); // 4. Enclosed characters ( 24C2 - 1F251 ) addUnicodeRangeToSet(filterSet, 0X24C2); addUnicodeRangeToSet(filterSet, 0X1F170, 0X1F251); // 6a. Additional emoticons ( 1F600 - 1F636 ) addUnicodeRangeToSet(filterSet, 0X1F600, 0X1F636); // 6b. Additional transport and map symbols ( 1F681 - 1F6C5 ) addUnicodeRangeToSet(filterSet, 0X1F681, 0X1F6C5); // 6c. Other additional symbols ( 1F30D - 1F567 ) addUnicodeRangeToSet(filterSet, 0X1F30D, 0X1F567); // 5. Uncategorized addUnicodeRangeToSet(filterSet, 0X1F004); addUnicodeRangeToSet(filterSet, 0X1F0CF); // 與6c. Other additional symbols ( 1F30D - 1F567 )重複 // 去掉重複部分雖然不去掉HashSet也不會重複,原範圍(0X1F300 - 0X1F5FF) addUnicodeRangeToSet(filterSet, 0X1F300, 0X1F30D); addUnicodeRangeToSet(filterSet, 0X1F5FB, 0X1F5FF); addUnicodeRangeToSet(filterSet, 0X00A9); addUnicodeRangeToSet(filterSet, 0X00AE); addUnicodeRangeToSet(filterSet, 0X0023); //阿拉伯數字0-9,配合0X20E3使用 //addUnicodeRangeToSet(filterSet, 0X0030, 0X0039); // 過濾掉203C開始後的2XXX 段落 //addUnicodeRangeToSet(filterSet, 0X203C, 0X24C2); addUnicodeRangeToSet(filterSet, 0X203C); addUnicodeRangeToSet(filterSet, 0X2049); //嚴格驗證的話需要判斷前面是否是數字 //Android上顯示和數字分開可以不判斷 addUnicodeRangeToSet(filterSet, 0X20E3); addUnicodeRangeToSet(filterSet, 0X2122); addUnicodeRangeToSet(filterSet, 0X2139); addUnicodeRangeToSet(filterSet, 0X2194, 0X2199); addUnicodeRangeToSet(filterSet, 0X21A9, 0X21AA); addUnicodeRangeToSet(filterSet, 0X231A, 0X231B); addUnicodeRangeToSet(filterSet, 0X23E9, 0X23EC); addUnicodeRangeToSet(filterSet, 0X23F0); addUnicodeRangeToSet(filterSet, 0X23F3); addUnicodeRangeToSet(filterSet, 0X25AA, 0X25AB); addUnicodeRangeToSet(filterSet, 0X25FB, 0X25FE); //TODO: 26XX 太雜全部過濾 addUnicodeRangeToSet(filterSet, 0X2600, 0X26FE); addUnicodeRangeToSet(filterSet, 0X2934, 0X2935); addUnicodeRangeToSet(filterSet, 0X2B05, 0X2B07); addUnicodeRangeToSet(filterSet, 0X2B1B, 0X2B1C); addUnicodeRangeToSet(filterSet, 0X2B50); addUnicodeRangeToSet(filterSet, 0X2B55); addUnicodeRangeToSet(filterSet, 0X3030); addUnicodeRangeToSet(filterSet, 0X303D); addUnicodeRangeToSet(filterSet, 0X3297); addUnicodeRangeToSet(filterSet, 0X3299); } public EmojiFilter() { super(); } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { // check black-list set for (int i = 0; i < source.length(); i++) { Log.e("字符",""+Integer.toHexString(source.charAt(i))); } Log.e("字符",""+source.toString() + " length: " + source.toString().length() + " ;bytes length: " + source.toString().getBytes().length); // Iterator<String> iterator = filterSet.iterator(); // while (iterator.hasNext()) { // String filter = iterator.next(); // if (filter.equals(source.toString())) { // LogUtil.e(filter + " length: " + filter.length() + // " ;bytes length: " + filter.getBytes().length); // for (int i= 0; i < source.length(); i++){ // LogUtil.e(Integer.toHexString(source.charAt(i))); // } // return ""; // } // } if (filterSet.contains(source.toString())) { Toast_Util.showText("不支持Emoji表情!"); return ""; } return source; }
然後給需要添加過濾的edittext 添加過濾器。
et_name.setFilters(new InputFilter[]{new EmojiFilter(),new InputFilter.LengthFilter(10)});
對於過濾器的其他屬性,請自己進行學習。好,今天的小技能就告訴大家了。
最後補充一點,因爲emoj表情庫的數據是會更新的,所以在我們做的這個需求的時候,儘量參考一下emoji表情庫,鏈接在這裏:http://apps.timwhitlock.info/emoji/tables/unicode