最近在用原生的控件和佈局繪製一些界面並使用,雖然這些都是Android基本知識,但是有的時候真的感覺力不從心,感覺有必要對Android常用的控件和佈局做一個系統的瞭解。後續一個月甚至更多的時間都會圍繞這個主題展開,畢竟這裏面還是有不少高級控件的,我也會盡量結合應用深入的進行了解。
上一篇:EditText 下一篇:RadioGroup
在上一篇中,我們介紹了非常重要的一個控件EditText,今天我們來介紹一下它的子類AutoCompleteTextView,還是一樣,首先看一下官方文檔對其的描述:
* <p>An editable text view that shows completion suggestions automatically * while the user is typing. The list of suggestions is displayed in a drop * down menu from which the user can choose an item to replace the content * of the edit box with.</p> * * <p>The drop down can be dismissed at any time by pressing the back key or, * if no item is selected in the drop down, by pressing the enter/dpad center * key.</p>
一個可以實現自動補全功能的EditText,自動補全的數據通過一個下拉彈窗顯示,用戶可以選擇提示內容替換掉EditText中的內容。下拉彈窗可以通過按返回鍵或者下拉彈窗中沒有選中項時按下enter實現。
上面說的其實已經比較清楚了,就是根據你當前的輸入自動下拉顯示你可以或者想要輸入的內容,當然彈出的內容你的提前編輯好並且添加進去。下面接着看:
* <p>The list of suggestions is obtained from a data adapter and appears * only after a given number of characters defined by * {@link #getThreshold() the threshold}.</p> * * <p>The following code snippet shows how to create a text view which suggests * various countries names while the user is typing:</p>
彈出的提示數據來自於你設置的適配器,並且是在一定的輸入字符過後纔會有提示,這個字符數量可以通過setThreshold()來設置,也可以通過getThreshold()來查看當前的設置。下面的代碼演示的具體的實現
好了,下面就來具體看看具體的代碼實現(先看摘自文檔的內容):
* ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, * android.R.layout.simple_dropdown_item_1line, COUNTRIES); * AutoCompleteTextView textView = (AutoCompleteTextView) * findViewById(R.id.countries_list); * textView.setAdapter(adapter); * } * * private static final String[] COUNTRIES = new String[] { * "Belgium", "France", "Italy", "Germany", "Spain" * };
上面的代碼很簡單
- 初始化構建適配器所需的數據
- 構建AutoCompleteTextView的適配器ArrayAdaptor實例
- AutoCompleteTextView添加適配器即可
說了那麼多,我們就來看看AutoCompleteTextView展示樣式:
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dropDownSelector="@color/colorPrimary"
android:hint="Please edit your country" />
autoCompleteTextView=findViewById(R.id.autoCompleteTextView);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line,
getResources().getStringArray(R.array.country_array));
autoCompleteTextView.setAdapter(adapter);
運行的結果:
上面就是AutoCompleteTextView的使用方式和展示樣式了,那我們看看有哪些重要屬性需要學習了,我們的參考還是文檔描述:
* @attr ref android.R.styleable#AutoCompleteTextView_completionHint:推薦選項提示 * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold:最少開始提示字符數目 * @attr ref android.R.styleable#AutoCompleteTextView_completionHintView:推薦提示的View * @attr ref android.R.styleable#AutoCompleteTextView_dropDownSelector:下拉選中項背景 * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth:下拉框寬度 * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight:下拉框高度 * @attr ref android.R.styleable#ListPopupWindow_dropDownVerticalOffset:垂直上下邊距 * @attr ref android.R.styleable#ListPopupWindow_dropDownHorizontalOffset:水平左右邊距
我們就按照上面的一個一個展開學習,首先看第一個
@attr ref android.R.styleable#AutoCompleteTextView_completionHint:推薦選項提示
在控件的具體屬性中我們可以通過XML或者接口實現設置:
android:completionHint="你是不是要找China?"
或者
autoCompleteTextView.setCompletionHint("你是不是要找China?");
如果感覺單詞的文本提示不好看,可以通過以下屬性來設置View實現推薦的效果
@attr ref android.R.styleable#AutoCompleteTextView_completionHintView:推薦提示的View
使用方式是通過xml實現
android:completionHintView="@layout/hint_view_layout"
關於這個屬性有一些需要注意的地方,我們首先看一下AutoCompleteTextView的部分源碼:
private TextView mHintView;
public void setCompletionHint(CharSequence hint) {
mHintText = hint;
if (hint != null) {
if (mHintView == null) {//如果mHintView爲null
final TextView hintView = (TextView) LayoutInflater.from(mPopupContext).inflate(
mHintResource, null).findViewById(R.id.text1);//找到mHintResource中id爲text1的TextView
hintView.setText(mHintText);
mHintView = hintView;//賦值給mHintView
mPopup.setPromptView(hintView);//彈出自定義的TextView
} else {
mHintView.setText(hint);
}
} else {
mPopup.setPromptView(null);
mHintView = null;
}
}
可見,我們設置的這個completionHintView本質是一個TextView,且id必須爲text1的id,否則就會報空指針異常。具體的解釋可參照AutocompleteTextview and CompletionHintView
從上面看出,我們至少要輸入兩個字符纔會有提示,我們可以通過第二個屬性進行設置,方式有以下兩種:
android:completionThreshold="1"
或者
autoCompleteTextView.setThreshold(1);
好了,我們接着往下看
@attr ref android.R.styleable#AutoCompleteTextView_dropDownSelector:下拉選中項背景
使用方式:
android:dropDownSelector="@color/colorPrimary"
好了,從上面我們可以看到,當推薦的內容過多時,下拉框的高度太高,影響用戶體驗,我們可以通過下面兩個屬性對下拉框的尺寸進行設置
* @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth:下拉框寬度
* @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight:下拉框高度
使用方式:
android:dropDownHeight="300dp"
android:dropDownWidth="200dp"
或者
autoCompleteTextView.setDropDownHeight(300);
autoCompleteTextView.setDropDownWidth(200);
最後兩個時設置邊距的屬性,使用方式如下:
autoCompleteTextView.setDropDownHorizontalOffset(50);
autoCompleteTextView.setDropDownVerticalOffset(50);
可見,這是下拉框相對於EditText的邊距,看一下源碼解釋就知道了(水平間距接口)
* <p>Sets the horizontal offset used for the auto-complete drop-down list.</p>
好了,到這裏,關於AutoCompleteTextView的介紹就到這裏了,下面我們接着把MultiAutoCompleteTextView也隨帶介紹一下,官方文檔描述如下:
* An editable text view, extending {@link AutoCompleteTextView}, that * can show completion suggestions for the substring of the text where * the user is typing instead of necessarily for the entire thing. * <p> * You must provide a {@link Tokenizer} to distinguish the * various substrings.
一個擴展了AutoCompleteTextView的EditText,也是能夠更加你輸入的字符進行提示,且其選擇的內容是追加在EditText文本後面。不是替換,新增加內容與之前內容可以通過設置Tokenizer來實現分割。
下面,我們直接看運行效果對比
<MultiAutoCompleteTextView
android:id="@+id/multiAutoCompleteTextView"
android:dropDownSelector="@color/colorPrimary"
android:hint="Please edit your hobbies"
android:completionThreshold="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
ArrayAdapter<String> adapter1=new ArrayAdapter<String>(this,android.
R.layout.simple_dropdown_item_1line,
getResources().getStringArray(R.array.hobby_array));
multiAutoCompleteTextView.setAdapter(adapter1);
multiAutoCompleteTextView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
multiAutoCompleteTextView.setDropDownHorizontalOffset(50);
multiAutoCompleteTextView.setDropDownVerticalOffset(50);
總結使用步驟也比較簡單:
- 初始化構建適配器所需的數據
- 構建MultiAutoCompleteTextView的適配器ArrayAdaptor實例
- MultiAutoCompleteTextView添加適配器
- MultiAutoCompleteTextView設置分隔符(可以自定義樣式)
下面我們就來自定義一個分隔符樣式,因爲上面採用的MultiAutoCompleteTextView類中自帶的分隔符CommaTokenizer,我們想自定義,因爲setTokenizer()接收的參數是一個MultiAutoCompleteTextView.Tokenizer的一個子類,所以我們自定義的分隔符類需要實現它,實現的方式我們結合上面使用的MultiAutoCompleteTextView.CommaTokenizer();具體代碼如下:
package aoto.com.commonwidgetandlayout.basic_widget.autoText;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.widget.MultiAutoCompleteTextView;
/**
* author:why
* created on: 2019/6/5 14:34
* description:
*/
public class SelfTokenizer implements MultiAutoCompleteTextView.Tokenizer {
@Override
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;
}
@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 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 + "-";
}
}
}
}
使用效果如下:
主要代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="aoto.com.commonwidgetandlayout.basic_widget.autoText.AutoTextActivity">
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:dropDownSelector="@color/colorPrimary"
android:hint="Please enter your country"
android:lines="1"
android:singleLine="true" />
<MultiAutoCompleteTextView
android:id="@+id/multiAutoCompleteTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:dropDownSelector="@color/colorPrimary"
android:hint="Please edit your birthday"
android:lines="1"
android:singleLine="true" />
</LinearLayout>
package aoto.com.commonwidgetandlayout.basic_widget.autoText;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.MultiAutoCompleteTextView;
import android.widget.TextView;
import java.util.ArrayList;
import aoto.com.commonwidgetandlayout.R;
import aoto.com.commonwidgetandlayout.basic_widget.checkedTextView.MyAdaptor;
/**
* @author why
* @date 2019-6-5 10:07:09
*/
public class AutoTextActivity extends AppCompatActivity {
private static final String TAG = "AutoTextActivityWhy";
AutoCompleteTextView autoCompleteTextView;
MultiAutoCompleteTextView multiAutoCompleteTextView;
private String content="";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto_text);
autoCompleteTextView=findViewById(R.id.autoCompleteTextView);
multiAutoCompleteTextView=findViewById(R.id.multiAutoCompleteTextView);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line,
getResources().getStringArray(R.array.country_array));
autoCompleteTextView.setAdapter(adapter);
autoCompleteTextView.setDropDownHorizontalOffset(50);
autoCompleteTextView.setDropDownVerticalOffset(50);
ArrayAdapter<String> adapter1=new ArrayAdapter<String>(this,android.
R.layout.simple_dropdown_item_1line,
getResources().getStringArray(R.array.time_array));
multiAutoCompleteTextView.setAdapter(adapter1);
//multiAutoCompleteTextView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
multiAutoCompleteTextView.setTokenizer(new SelfTokenizer());
multiAutoCompleteTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
content=multiAutoCompleteTextView.getText().toString();
multiAutoCompleteTextView.setText(content.substring(0,content.lastIndexOf("-")));
multiAutoCompleteTextView.setSelection(content.length()-1);
return false;
}
});
}
}
好了,端午節放假前的一天,終於寫完了,還是有點累的,喜歡的掃碼關注一波喲。
注:歡迎掃碼關注