Android 邮箱自动补全-MultiAutoCompleteTextView实现
因為項目需要,要寫一個郵箱自動補全的EditText,剛開始考慮使用AutoCompleteTextView來實現,但是滿足不到需求官方組件太low了。。。
先來介紹下AutoCompleteTextView 的使用:
Activity
XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="AutoCompleteTextView實現"android:textColor="@android:color/black" /><AutoCompleteTextView android:id="@+id/autoCompleteTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:completionThreshold="1"/> </LinearLayout>使用方法很簡單,獲取到組件然后設置一個彈出的Adapter就能完成一個自動提示。
但是這個組件有幾個特性不是很滿足我們的需求。
1.默認是第二個字母開始匹配
2.整體內容匹配模式 Belgium 我們只能輸入B ,Be,Bel等才會匹配
注:郵箱格式為123456@XX.com,整體內容肯定不行。
下面我們又看到一個MultiAutoCompleteTextView組件,來看下MultiAutoCompleteTextView能否滿足我們的需求
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.MultiAutoCompleteTextView;public class MainActivity extends AppCompatActivity {private static final String[] COUNTRIES = new String[]{"Belgium", "France", "Italy", "Germany", "Spain"};private AutoCompleteTextView mAutoCompleteTextView;private MultiAutoCompleteTextView mMultiAutoCompleteTextView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);mMultiAutoCompleteTextView = (MultiAutoCompleteTextView) findViewById(R.id.multiAutoCompleteTextView);ArrayAdapter<String> adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line, COUNTRIES);mAutoCompleteTextView.setAdapter(adapter);mMultiAutoCompleteTextView.setAdapter(adapter);mMultiAutoCompleteTextView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());}}XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="AutoCompleteTextView實現"android:textColor="@android:color/black" /><AutoCompleteTextView android:id="@+id/autoCompleteTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:completionThreshold="1" /><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="MultiAutoCompleteTextView實現"android:textColor="@android:color/black" /><MultiAutoCompleteTextView android:id="@+id/multiAutoCompleteTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:completionThreshold="1" /> </LinearLayout>
Activity
經過查詢API 我們知道 MultiAutoCompleteTextView 繼承于 AutoCompleteTextView 繼承于EditText
API中在MultiAutoCompleteTextView 提供了一個接口MultiAutoCompleteTextView.Tokenizer 可以用來匹配提示的子字符串。好吧,勉強能實現需求。
首先看MultiAutoCompleteTextView源碼中有一個對Tokenizer接口的實現!然后換成我們的。
根據MultiAutoCompleteTextView源碼中的實現,我們知道Tokenizer的實現方式。
import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; import android.widget.MultiAutoCompleteTextView;public class EmailAutoTokenizer implements MultiAutoCompleteTextView.Tokenizer {@Overridepublic int findTokenEnd(CharSequence text, int cursor) {int i = cursor;int len = text.length();while (i < len) {if (text.charAt(i) == '@') {return i;} else {i++;}}return len;}@Overridepublic int findTokenStart(CharSequence text, int cursor) {int index = text.toString().indexOf("@");if (index < 0) {index = text.length();}if (index >= findTokenEnd(text, cursor)) {index = 0;}return index;}@Overridepublic CharSequence terminateToken(CharSequence text) {int i = text.length();while (i > 0 && text.charAt(i - 1) == ' ') {i--;}if (i > 0 && text.charAt(i - 1) == '@') {return text;} else {if (text instanceof Spanned) {SpannableString sp = new SpannableString(text);TextUtils.copySpansFrom((Spanned) text, 0, text.length(), Object.class, sp, 0);return sp;} else {return text;}}} }在Activity中把Tokenizer換成我們自己的看下效果 mMultiAutoCompleteTextView.setTokenizer(new EmailAutoTokenizer());
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.MultiAutoCompleteTextView;public class MainActivity extends AppCompatActivity {private String[] email_sufixs = new String[]{"@qq.com", "@163.com", "@126.com", "@gmail.com", "@sina.com", "@hotmail.com","@yahoo.cn", "@sohu.com", "@foxmail.com", "@139.com", "@yeah.net", "@vip.qq.com", "@vip.sina.com"};private AutoCompleteTextView mAutoCompleteTextView;private MultiAutoCompleteTextView mMultiAutoCompleteTextView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);mMultiAutoCompleteTextView = (MultiAutoCompleteTextView) findViewById(R.id.multiAutoCompleteTextView);ArrayAdapter<String> adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line, email_sufixs);mAutoCompleteTextView.setAdapter(adapter);mMultiAutoCompleteTextView.setAdapter(adapter);mMultiAutoCompleteTextView.setTokenizer(new EmailAutoTokenizer());} }看下最后的效果圖,當然我們還需要對彈出框進行調整下,自己去查詢API吧!提供有方法。
正當我高興的時候,萬惡的產品Dog給我加一個右邊刪除效果,丟一個驗證規則過來!
在@之后輸入字母,從輸入的字母開始suggest郵箱
點擊suggest的郵箱,郵箱被輸入到郵箱輸入欄里,光標移動到下一text box
例:
1. 輸入:monoqn → 不suggest
1. 輸入:monoqn@ → 不suggest
1. 輸入:monoqn@i → monoqn@i.softbank.jp/monoqn@icloud.com
1. 輸入:monoqn@ic → monoqn@icloud.com
下面先驗證規則:
1.在@之后輸入字母,從輸入的字母開始suggest郵箱。
很簡單android:completionThreshold=”2” 設置輸入幾個字符之后顯示下拉菜單,默認為2個。不用管就行
2.點擊suggest的郵箱,郵箱被輸入到郵箱輸入欄里,光標移動到下一text box
也簡單MultiAutoCompleteTextView中有OnItemClickListener事件,
3.顯示規則
看下了滿足需求,666666!
最后一個右邊加入刪除按鈕!本寶寶自定義一個就OK。
import android.content.Context; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.MultiAutoCompleteTextView;public class CleanableMultiAutoCompleteTextView extends MultiAutoCompleteTextView {private Drawable mRightDrawable;public CleanableMultiAutoCompleteTextView(Context context) {super(context);init();}public CleanableMultiAutoCompleteTextView(Context context, AttributeSet attrs) {super(context, attrs);init();}public CleanableMultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init() {// getCompoundDrawables:// Returns drawables for the left, top, right, and bottom borders.Drawable[] drawables = this.getCompoundDrawables();// get right drawable in layout.xml that is android:drawableRightmRightDrawable = drawables[2];setOnFocusChangeListener(new FocusChangeListenerImpl());addTextChangedListener(new TextWatcherImpl());setClearDrawableVisible(false);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_UP:boolean isClean = (event.getX() > (getWidth() - getTotalPaddingRight()))&& (event.getX() < (getWidth() - getPaddingRight()));if (isClean) {setText("");}break;}return super.onTouchEvent(event);}private class FocusChangeListenerImpl implements OnFocusChangeListener {@Overridepublic void onFocusChange(View v, boolean hasFocus) {if (hasFocus) {boolean isVisible = !TextUtils.isEmpty(getText());setClearDrawableVisible(isVisible);} else {setClearDrawableVisible(false);}}}private class TextWatcherImpl implements TextWatcher {@Overridepublic void afterTextChanged(Editable s) {boolean isVisible = !TextUtils.isEmpty(getText());setClearDrawableVisible(isVisible);}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {// no-op}@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {// no-op}}public void setClearDrawableVisible(boolean isVisible) {Drawable rightDrawable = isVisible ? mRightDrawable : null;setCompoundDrawables(getCompoundDrawables()[0],getCompoundDrawables()[1], rightDrawable,getCompoundDrawables()[3]);} }有小伙伴需求是需要把輸入的值放在@前面,感謝這位小伙伴的意見,后續我會把代碼更新上來。
下載地址:https://github.com/liliLearn/AutoCompleteEmail-sample
總結
以上是生活随笔為你收集整理的Android 邮箱自动补全-MultiAutoCompleteTextView实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DL2 - Improving Deep
- 下一篇: 简历模板哪里找?这几个免费网站一定要收藏