編輯:關於Android編程
Android:使用AppCompatAutoCompleteTextView:我們先看看實現的效果吧,也就是我們俗話說的自動提示功能。這裡我實現了點擊AppCompatAutoCompleteTextView就會彈出提示框,以及不輸入內容時也顯示提示框。這裡主要是熟悉用法。還有很多很多api,請大家自行了解。

因為例子中提示的內容是Language,所以就建立類了
Language.java
public class Language {
public String name;
public int icon;
}
子項的布局文件item.xml。這裡就顯得很簡單了。
Activity布局文件activity_main.xml
為什麼需要繼承AppCompatAutoCompleteTextView呢?是因為系統自帶的AppCompatAutoCompleteTextView給提示的時候,輸入框的內容長度至少要大於1。但是我們有時候是需要不輸入內容就給出提示的,所以就需要重寫AppCompatAutoCompleteTextView。
MyAutoCompleteTextView .java
public class MyAutoCompleteTextView extends AppCompatAutoCompleteTextView {
public MyAutoCompleteTextView(Context context) {
super(context);
}
public MyAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean enoughToFilter() {
return true;
}
}
其實又顯示MyAutoCompleteTextView 類有點冗余了,也就是重寫了enoughToFilter()方法,一直返回true。有興趣的,可以看看自帶的AutoCompleteTextView 返回的是什麼。
接著我們為MyAutoCompleteTextView寫Adapter了。這裡直接使用ArrayAdapter好了。其實如果沒有特殊需求,ArrayAdapter能滿足我們很大的需求。其實上述功能肯定是需要用到Filter的(過濾功能)。而ArrayAdapter已經申明了實現Filterable接口了。不過為了更好的理解功能,我還是聲明實現Filterable接口。
MyAdapter.java
首先需要聲明幾個變量
// 經過過濾的數組 private ArrayListlanguages; // 沒有經過過濾的數組 private ArrayList origin; private Context context; private int layoutId;
核心變量是languages和origin。
構造函數就是依次為這些變量賦值。
public MyAdapter(Context context, int resource, ArrayList languages) {
super(context, resource);
this.languages = languages;
this.origin = languages;
this.context = context;
this.layoutId = resource;
}
這裡最好重寫兩個方法,一個是getItem(),另一個是getCount()。如果不寫,可能會導致不顯示
@Override
public Language getItem(int position) {
return languages == null ? null : languages.get(position);
}
@Override
public int getCount() {
return languages == null ? 0 : languages.size();
}
為了實現緩存,我們肯定是要寫getView方法的。所以我們得先定義viewHolder,作為MyAdapter的內部類
private class ViewHolder {
TextView name;
ImageView icon;
}
好了,寫getView()
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
ViewHolder holder;
if(null == convertView) {
convertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(languages.get(position).name);
holder.icon.setBackgroundResource(languages.get(position).icon);
return convertView;
}
通過view自帶的setTag和getTag方法實現view的復用。
前面說到,MyAdapter的聲明是這樣的
public class MyAdapter extends ArrayAdapter implements Filterable
要就要重寫getFilter()方法了。
我們先自定義Filter
private class MyFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(null == constraint || 0 == constraint.length()) {
constraint = "";
}
// 這裡做一些簡單的過濾
String condition = String.valueOf(constraint).toLowerCase();
List temp = new ArrayList<>();
for (Language language : origin) {
if (language.name.toLowerCase().contains(condition)) {
temp.add(language);
}
}
results.values = temp;
results.count = temp.size();
// 返回的results會在publishResult()函數中得到
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
languages = (ArrayList) results.values;
// 更新視圖
notifyDataSetChanged();
}
}
這下簡單了,getFilter()方法返回一個MyFilter對象就行了。
public Filter getFilter() {
return new MyFilter();
}
好了,上述的話,MyAdapter就實現完畢了。
那我們可以在Activity中使用了。
MainActivity.java
// 初始化數據
final ArrayList languages = new ArrayList<>();
Language one = new Language();
one.name = "Java";
one.icon = R.mipmap.java;
languages.add(one);
Language two = new Language();
two.name = "c";
two.icon = R.mipmap.c;
languages.add(two);
Language three = new Language();
three.name = "Python";
three.icon = R.mipmap.python;
languages.add(three);
Language four = new Language();
four.name = "gradle";
four.icon = R.mipmap.gradle;
languages.add(four);
Language five = new Language();
five.name = "php";
five.icon = R.mipmap.php;
languages.add(five);
Language six = new Language();
six.name = "groovy";
six.icon = R.mipmap.groovy;
languages.add(six);
上述的圖標都是自己下載的,就隨意下載了一些。
使用Adapter
MyAdapter myAdapter = new MyAdapter(this, R.layout.item, languages);
final MyAutoCompleteTextView textView = (MyAutoCompleteTextView) this.findViewById(R.id.tv_test);
textView.setAdapter(myAdapter);
為了進一步改善交互過程,點擊MyAutoCompleteTextView也應該彈出提示內容才行。
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.showDropDown();
}
});
並且,點擊了MyAutoCompleteTextView的子項也應該要顯示出來吧?值得開心的是MyAutoCompleteTextView有setOnItemClickListener方法,有點類似於ListView
textView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
Language language = languages.get(position);
textView.setText(language.name);
}
});
最後說道,這裡為什麼要用到AppCompatAutoCompleteTextView,而不是AutoCompleteTextView。因為AppCompatAutoCompleteTextView更能兼容好版本的Android系統,所以就使用AppCompatAutoCompleteTextView
至於AppCompatAutoCompleteTextView還有其他強大的功能,就需要自己去探索了,會了基本用法,其他的應該不難。
補充一下,其實AppCompatAutoCompleteTextView內部有一個ListPopupWindow,提示的內容就是用ListPopupWindow實現的。而ListPopupWindow我們可以理解為是ListView+PopupWindow。其實也就是說,我們可以自己實現AppCompatAutoCompleteTextView,自定義一個View,裡面是一個輸入框和PopupWindow,PopupWindow裡面又有ListView。如果不考慮兼容問題的話,實現起來應該不算太難。
Android Configuration橫豎屏切換時Activity生命周期調用
問題:橫豎屏切換時Activity的生命周期?測試環境:華為mate7 package com.virglass.beyond.activity;import
Android 開源柱狀圖分析實現
在平時開發中柱狀形狀偶爾會有項目需求,由於又一次開發需要,去找開源的組件都不好用,要不調用很不方便,要不它們類庫太笨重,下面介紹一個輕巧方便控件,原理就是用View 重新
Android編程之SurfaceView學習示例詳解
本文實例講述了Android編程之SurfaceView學習示例。分享給大家供大家參考,具體如下:SurfaceView是View的子類,使用的方式與任何View所派生的
Android自定義組件之日歷控件-精美日歷實現(內容、樣式可擴展)
需求我們知道,Android系統本身有自帶的日歷控件,網絡上也有很多開源的日歷控件資源,但是這些日歷控件往往樣式較單一,API較多,不易於在實際項目中擴展並實現出符合具體
Android插件化開發之AMS與應用程序(客戶端ActivityThread、Instrumentation、Activity)通信模型分析
今天主要分析下ActivityManagerService(服務端) 與