Android 邮箱自动补全-MultiAutoCompleteTextView实现
因?yàn)轫?xiàng)目需要,要寫(xiě)一個(gè)郵箱自動(dòng)補(bǔ)全的EditText,剛開(kāi)始考慮使用AutoCompleteTextView來(lái)實(shí)現(xiàn),但是滿足不到需求官方組件太low了。。。
先來(lái)介紹下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實(shí)現(xiàn)"android:textColor="@android:color/black" /><AutoCompleteTextView android:id="@+id/autoCompleteTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:completionThreshold="1"/> </LinearLayout>使用方法很簡(jiǎn)單,獲取到組件然后設(shè)置一個(gè)彈出的Adapter就能完成一個(gè)自動(dòng)提示。
但是這個(gè)組件有幾個(gè)特性不是很滿足我們的需求。
1.默認(rèn)是第二個(gè)字母開(kāi)始匹配
2.整體內(nèi)容匹配模式 Belgium 我們只能輸入B ,Be,Bel等才會(huì)匹配
注:郵箱格式為123456@XX.com,整體內(nèi)容肯定不行。
下面我們又看到一個(gè)MultiAutoCompleteTextView組件,來(lái)看下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實(shí)現(xiàn)"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實(shí)現(xiàn)"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
經(jīng)過(guò)查詢API 我們知道 MultiAutoCompleteTextView 繼承于 AutoCompleteTextView 繼承于EditText
API中在MultiAutoCompleteTextView 提供了一個(gè)接口MultiAutoCompleteTextView.Tokenizer 可以用來(lái)匹配提示的子字符串。好吧,勉強(qiáng)能實(shí)現(xiàn)需求。
首先看MultiAutoCompleteTextView源碼中有一個(gè)對(duì)Tokenizer接口的實(shí)現(xiàn)!然后換成我們的。
根據(jù)MultiAutoCompleteTextView源碼中的實(shí)現(xiàn),我們知道Tokenizer的實(shí)現(xiàn)方式。
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());} }看下最后的效果圖,當(dāng)然我們還需要對(duì)彈出框進(jìn)行調(diào)整下,自己去查詢API吧!提供有方法。
正當(dāng)我高興的時(shí)候,萬(wàn)惡的產(chǎn)品Dog給我加一個(gè)右邊刪除效果,丟一個(gè)驗(yàn)證規(guī)則過(guò)來(lái)!
在@之后輸入字母,從輸入的字母開(kāi)始suggest郵箱
點(diǎn)擊suggest的郵箱,郵箱被輸入到郵箱輸入欄里,光標(biāo)移動(dòng)到下一text box
例:
1. 輸入:monoqn → 不suggest
1. 輸入:monoqn@ → 不suggest
1. 輸入:monoqn@i → monoqn@i.softbank.jp/monoqn@icloud.com
1. 輸入:monoqn@ic → monoqn@icloud.com
下面先驗(yàn)證規(guī)則:
1.在@之后輸入字母,從輸入的字母開(kāi)始suggest郵箱。
很簡(jiǎn)單android:completionThreshold=”2” 設(shè)置輸入幾個(gè)字符之后顯示下拉菜單,默認(rèn)為2個(gè)。不用管就行
2.點(diǎn)擊suggest的郵箱,郵箱被輸入到郵箱輸入欄里,光標(biāo)移動(dòng)到下一text box
也簡(jiǎn)單MultiAutoCompleteTextView中有OnItemClickListener事件,
3.顯示規(guī)則
看下了滿足需求,666666!
最后一個(gè)右邊加入刪除按鈕!本寶寶自定義一個(gè)就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]);} }有小伙伴需求是需要把輸入的值放在@前面,感謝這位小伙伴的意見(jiàn),后續(xù)我會(huì)把代碼更新上來(lái)。
下載地址:https://github.com/liliLearn/AutoCompleteEmail-sample
總結(jié)
以上是生活随笔為你收集整理的Android 邮箱自动补全-MultiAutoCompleteTextView实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: DL2 - Improving Deep
- 下一篇: Android Studio更换项目界面