1.分析AutoCompleteTextView为什么可以实现自动补全分析源码
if (valueText.startsWith(prefixString)) {
newValues.add(value);
} else {
final String[] words = valueText.split(" ");
final int wordCount = words.length;
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newValues.add(value);
break;
}
}
}
2.
我们反过来再研究一下ArrayAdapter,它除了是BaseAdapter的子类,它还实现了 Filterable 接口!我们在AutoAdapter中,实现该接口,并返回一个自定义的 Filter,所以
我们必须实现两个重要的方法:
protected FilterResults performFiltering(CharSequence prefix)
在这个方法里面定制过滤策略,根据输入的prefix对数据进行过滤,并组装成FilterResults 结果返回;
protected void publishResults(CharSequence constraint, FilterResults results)
这个方法则是发布结果用的,把上面方法的结果按照一定的要求进行处理后,通知Adapter进行数据视图的刷新
总结:
按照 AutoCompleteTextView 的工作流程,它依赖两个
组件,Adapter 和 Filter,一个是视图的处理,一个是数据过滤处理,对这两个组件进行深度定制,我们就可以随心所欲了。
3.下面是我自己写的自定义AutoCompleteTextView可以按照拼音搜索(就是根据拼音在数据库中查找)
public class MyAutoCompleteTextView1 extends AutoCompleteTextView {
private DB4Helper mDb4Helper;
public MyAutoCompleteTextView1(Context context){
super(context);
init(context);
}
public MyAutoCompleteTextView1(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public void init(final Context context){
new Thread(new Runnable() {
@Override
public void run() {
mDb4Helper=DB4Helper.getInstance(context);
}
}).start();
final MyAdapter myAdapter=new MyAdapter(context);
setAdapter(myAdapter);
addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
myAdapter.mList.clear();
myAdapter.mList=mDb4Helper.getAddsTableDB(s.toString());
myAdapter.notifyDataSetChanged();
showDropDown();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
setThreshold(1);
}
public class MyAdapter extends BaseAdapter implements Filterable{
List<String> mList;
private Context mContext;
private MyFilter mFilter;
public MyAdapter(Context context){
this.mContext=context;
mList=new ArrayList<String>();
}
@Override
public int getCount() {
return mList==null?0:mList.size();
}
@Override
public Object getItem(int position) {
return mList==null?null:mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
TextView tv=(TextView) LayoutInflater.from(mContext).inflate(R.layout.tv,null);
tv.setTextColor(Color.BLACK);
tv.setTextSize(20);
convertView=tv;
}
TextView tvx=(TextView) convertView;
tvx.setText(mList.get(position));
return tvx;
}
@Override
public android.widget.Filter getFilter() {
if(mFilter==null){
mFilter=new MyFilter();
}
return mFilter;
}
private class MyFilter extends android.widget.Filter{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (mList == null) {
mList = new ArrayList<String>();
}
results.values = mList;
results.count = mList.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint,FilterResults results) {
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
}
public class DB4Helper extends SQLiteOpenHelper {
<span style="white-space:pre"> </span>private final static String tag = "DB4Bank";
<span style="white-space:pre"> </span>private static final int DATABASE_VERSION = 1;
<span style="white-space:pre"> </span>private static String DB_NAME_DB4 = "tlbank.db";
<span style="white-space:pre"> </span>private static DB4Helper mInstance;
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public static DB4Helper getInstance(Context context) {
<span style="white-space:pre"> </span>if(mInstance==null){
<span style="white-space:pre"> </span>mInstance=new DB4Helper(context);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return mInstance;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public DB4Helper(Context context){
<span style="white-space:pre"> </span>super(context,DB_NAME_DB4,null,DATABASE_VERSION);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public DB4Helper(Context context, String name, CursorFactory factory,
<span style="white-space:pre"> </span>int version) {
<span style="white-space:pre"> </span>super(context, name, factory, version);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void onCreate(SQLiteDatabase db) {
<span style="white-space:pre"> </span>String sql4Adds = "create table AddsTable(m_id integer primary key autoincrement,"
<span style="white-space:pre"> </span>+ "adds varchar(255),addspinyin varchar(500),addszimu varchar(255))";
<span style="white-space:pre"> </span>db.execSQL(sql4Adds);
<span style="white-space:pre"> </span>initAdds(db);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 里面说的数据读者可以自行添加
<span style="white-space:pre"> </span> * @param db
<span style="white-space:pre"> </span> */
public void initAdds(SQLiteDatabase db){
<span style="white-space:pre"> </span>ArrayList<String> list=new ArrayList<String>();
<span style="white-space:pre"> </span>for (String sql : list) {
<span style="white-space:pre"> </span>db.execSQL(sql);
<span style="white-space:pre"> </span>}
}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public ArrayList<String> getAddsTableDB(String guanjianzi) {
<span style="white-space:pre"> </span>ArrayList<String> list = new ArrayList<String>();
<span style="white-space:pre"> </span>Cursor cursor = null;
<span style="white-space:pre"> </span>String sql="select adds from AddsTable where" +
<span style="white-space:pre"> </span>" adds like '%"+guanjianzi+"%'or addszimu like '%"+guanjianzi+"%'";
<span style="white-space:pre"> </span>cursor=mInstance.getWritableDatabase().rawQuery(sql,null);
<span style="white-space:pre"> </span> if(cursor==null){
<span style="white-space:pre"> </span> <span style="white-space:pre"> </span>return list;
<span style="white-space:pre"> </span> }
<span style="white-space:pre"> </span>while(cursor.moveToNext()){
<span style="white-space:pre"> </span> list.add(cursor.getString(cursor.getColumnIndexOrThrow("adds")));
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return list;
<span style="white-space:pre"> </span>}
}
3.总结AutoCompleteTextView就是PopupWindow 和EditText 加Filterable 进行数据的过滤,也可以自己用EditText加PopupWindow实现一个AutoCompleteTextView ,但是会出现焦点问题,有兴趣的读者可以试试!