Activity
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; public class MainActivity extends AppCompatActivity { private static final String[] COUNTRIES = new String[]{ "Belgium", "France", "Italy", "Germany", "Spain" }; private AutoCompleteTextView mAutoCompleteTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView); ArrayAdapter<String> adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES); mAutoCompleteTextView.setAdapter(adapter); } }
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實現(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>
使用方法很簡單,獲取到組件然后設(shè)置一個彈出的Adapter就能完成一個自動提示。
但是這個組件有幾個特性不是很滿足我們的需求。
1.默認(rèn)是第二個字母開始匹配
2.整體內(nèi)容匹配模式 Belgium 我們只能輸入B ,Be,Bel等才會匹配
注:郵箱格式為123456@XX.com,整體內(nèi)容肯定不行。
下面我們又看到一個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; @Override protected 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實現(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實現(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)過查詢API 我們知道 MultiAutoCompleteTextView 繼承于 AutoCompleteTextView 繼承于EditText
API中在MultiAutoCompleteTextView 提供了一個接口MultiAutoCompleteTextView.Tokenizer 可以用來匹配提示的子字符串。好吧,勉強能實現(xiàn)需求。
首先看MultiAutoCompleteTextView源碼中有一個對Tokenizer接口的實現(xiàn)!然后換成我們的。
/** * This simple Tokenizer can be used for lists where the items are * separated by a comma and one or more spaces. */ public static class CommaTokenizer implements Tokenizer { public int findTokenStart(CharSequence text, int cursor) { int i = cursor; while (i > 0 && text.charAt(i – 1) != \\\’,\\\’) { i–; } while (i < cursor && text.charAt(i) == \\\’ \\\’) { i ; } return i; } public 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; } public 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 ", "; } } } }
根據(jù)MultiAutoCompleteTextView源碼中的實現(xiàn),我們知道Tokenizer的實現(xiàn)方式。
import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; import android.widget.MultiAutoCompleteTextView; public class EmailAutoTokenizer implements MultiAutoCompleteTextView.Tokenizer { @Override public 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; } @Override public 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; } @Override public 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; @Override protected 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)然我們還需要對彈出框進行調(diào)整下,自己去查詢API吧!提供有方法。
正當(dāng)我高興的時候,萬惡的產(chǎn)品Dog給我加一個右邊刪除效果,丟一個驗證規(guī)則過來!
在@之后輸入字母,從輸入的字母開始suggest郵箱
點擊suggest的郵箱,郵箱被輸入到郵箱輸入欄里,光標(biāo)移動到下一text box
例:
1. 輸入:monoqn → 不suggest
1. 輸入:monoqn@ → 不suggest
1. 輸入:monoqn@i → monoqn@i.softbank.jp/monoqn@icloud.com
1. 輸入:monoqn@ic → monoqn@icloud.com
下面先驗證規(guī)則:
1.在@之后輸入字母,從輸入的字母開始suggest郵箱。
很簡單android:completionThreshold=”2” 設(shè)置輸入幾個字符之后顯示下拉菜單,默認(rèn)為2個。不用管就行
2.點擊suggest的郵箱,郵箱被輸入到郵箱輸入欄里,光標(biāo)移動到下一text box
也簡單MultiAutoCompleteTextView中有OnItemClickListener事件,
email.setOnItemClickListener((parent, view1, position, id) -> password.requestFocus());
3.顯示規(guī)則
看下了滿足需求,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:drawableRight mRightDrawable = drawables[2]; setOnFocusChangeListener(new FocusChangeListenerImpl()); addTextChangedListener(new TextWatcherImpl()); setClearDrawableVisible(false); } @Override public 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 { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { boolean isVisible = !TextUtils.isEmpty(getText()); setClearDrawableVisible(isVisible); } else { setClearDrawableVisible(false); } } } private class TextWatcherImpl implements TextWatcher { @Override public void afterTextChanged(Editable s) { boolean isVisible = !TextUtils.isEmpty(getText()); setClearDrawableVisible(isVisible); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // no-op } @Override public 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]); } }
更多關(guān)于云服務(wù)器,域名注冊,虛擬主機的問題,請訪問西部數(shù)碼官網(wǎng):www.bingfeng168.cn