一、AutoCompleteTextView源码
1.1 设置适配器
...
//该适配器必须继承ListAdapter并且实现Filterable接口
public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
if (mObserver == null) {
mObserver = new PopupDataSetObserver(this);
} else if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mObserver);
}
mAdapter = adapter;
if (mAdapter != null) {
//获取适配器中的过滤器
mFilter = ((Filterable) mAdapter).getFilter();
adapter.registerDataSetObserver(mObserver);
} else {
mFilter = null;
}
mPopup.setAdapter(mAdapter);
}
...
1.2 构造函数
public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes, Theme popupTheme) {
super(context, attrs, defStyleAttr, defStyleRes);
....
mPopup = new ListPopupWindow(mPopupContext, attrs, defStyleAttr, defStyleRes);
mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
mPopup.setListSelector(popupListSelector);
//给Popuwindow添加条目点击事件
mPopup.setOnItemClickListener(new DropDownItemClickListener());
//默认超过两个字符之后才开发执行过滤操作
mThreshold = a.getInt(R.styleable.AutoCompleteTextView_completionThreshold, 2);
//创建时已经自己给自己添加了一个文本内容变化的监听
addTextChangedListener(new MyWatcher());
mPassThroughClickListener = new PassThroughClickListener();
super.setOnClickListener(mPassThroughClickListener);
}
1.4 DropDownItemClickListener
...
private class DropDownItemClickListener implements AdapterView.OnItemClickListener {
public void onItemClick(AdapterView parent, View v, int position, long id) {
performCompletion(v, position, id);
}
}
...
private void performCompletion(View selectedView, int position, long id) {
...
//填充控件文本
replaceText(convertSelectionToString(selectedItem));
...
}
1.5 MyWatcher
private class MyWatcher implements TextWatcher {
public void afterTextChanged(Editable s) {
//执行过滤操作
doAfterTextChanged();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
doBeforeTextChanged();
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}
二、AutoCompleteTextView使用
2.1 自定义适配器CompleteAdapter
package yang.study.com.appcompletetextviewdemo;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import java.util.List;
public class CompleteAdapter extends BaseAdapter implements Filterable {
private final Context context;
private final List<ProvinceModel> provinceModelList;
public CompleteAdapter(Context context, List<ProvinceModel> provinceModelList) {
this.context = context;
this.provinceModelList = provinceModelList;
}
public void setData(Object objects) {
provinceModelList.clear();
if (objects != null) {
List<ProvinceModel> provinceModelListResult = (List<ProvinceModel>) objects;
provinceModelList.addAll(provinceModelListResult);
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
@Override
public int getCount() {
Log.e("Filter::", "CompleteAdapter::getCount==");
return provinceModelList == null ? 0 : provinceModelList.size();
}
@Override
public ProvinceModel getItem(int position) {
return provinceModelList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(context, android.R.layout.simple_list_item_1, null);
}
TextView tv = (TextView) convertView;
tv.setText(position + "数据id==" + getItem(position).provinceName);
return convertView;
}
/**
* 给AppCompatAutoCompleteTextView设置Adapter之后就会被调用
* @return
*/
@Override
public Filter getFilter() {
return new CompleteFilterable(provinceModelList, this);
}
}
2.1 自定义过滤器CompleteFilterable
package yang.study.com.appcompletetextviewdemo;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Filter;
import java.util.ArrayList;
import java.util.List;
public class CompleteFilterable extends Filter {
private List<ProvinceModel> provinceModelList = new ArrayList<>();
private CompleteAdapter completeAdapter;
public CompleteFilterable(List<ProvinceModel> provinceModelList, CompleteAdapter completeAdapter) {
this.provinceModelList.addAll(provinceModelList);
this.completeAdapter = completeAdapter;
}
/**
* 执行过滤
* 如果采取服务器端过滤之后返回结果,那么该方法不用执行
* 任何过滤操作。只需要将查询结果赋值给FilterResults即可
*
* @param constraint
* @return
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<ProvinceModel> provinceModelArrayList = new ArrayList<>();
if (!TextUtils.isEmpty(constraint)) {
for (int i = 0; i < provinceModelList.size(); i++) {
ProvinceModel provinceModel = provinceModelList.get(i);
if (provinceModel.provinceName.contains(constraint)) {
provinceModelArrayList.add(provinceModel);
}
}
}
filterResults.count = provinceModelArrayList.size();
filterResults.values = provinceModelArrayList;
return filterResults;
}
/**
* 发布过滤结果
*
* @param constraint
* @param results
*/
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
completeAdapter.setData(results.values);
}
/**
* 点击联想搜索结果条目的时候使用
*
* @param resultValue
* @return
*/
@Override
public CharSequence convertResultToString(Object resultValue) {
return resultValue == null ? "" : ((ProvinceModel) resultValue).provinceName;
}
}
三、注意事项
1.在Activity中使用的时候如果发现软件盘出现将PopupWindow顶起,那么可以在清单文件中给Activity添加android:windowSoftInputMode="adjustNothing"2.在Dialog中使用的时候如果发现软件盘出现将PopupWindow顶起,那么可以给该Dialog的window设置window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);