public class AutoCompleteSearchDialog extends Dialog { private Activity activity; ImageView accept, cancel; Dialog dialog; AutoCompleteSearchDialogListener listener; EditText searchview; private AutoLinearLayout search_container; private ListView searchAutoComplete; private SearchAutoCompleteAdapter mAdapter; String hint; String inputContent; private SearchItem mSelectedItem; private List<SearchItem> mSearchDatas = new ArrayList<SearchItem>(); public AutoCompleteSearchDialog(Activity activity, List<SearchItem> searchDatas, String hint, AutoCompleteSearchDialogListener listener){ super(activity, R.style.DiscoverDialog); this.activity=activity; this.dialog = this; this.hint = hint; mSearchDatas.clear(); mSearchDatas.addAll(searchDatas); this.listener = listener; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialog_auto_complete_search); searchview = (EditText) findViewById(R.id.dialog_input_search); accept = (ImageView) findViewById(R.id.dialog_input_accept); cancel = (ImageView) findViewById(R.id.dialog_input_cancel); search_container=(AutoLinearLayout)findViewById(R.id.search_container); searchview.setHint(hint); searchAutoComplete=(ListView)findViewById(R.id.lv_search); mAdapter=new SearchAutoCompleteAdapter(activity,mSearchDatas); mAdapter.setDataRecord(mSearchDatas); searchAutoComplete.setAdapter(mAdapter); searchAutoComplete.setTextFilterEnabled(true); searchAutoComplete.setOnItemClickListener(new ItemClick()); accept.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View arg0) { dialog.dismiss(); inputContent=searchview.getText().toString(); if(TextUtils.isEmpty(inputContent)){ mSelectedItem=null; } listener.OnAcceptClick(mSelectedItem); } }); cancel.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View arg0) { dialog.dismiss(); } }); searchview.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { mAdapter.getFilter().filter(s.toString()); search_container.setVisibility(View.VISIBLE); // 使用用户输入的内容对ListView的列表项进行过滤,有黑框 //// lv.setFilterText(String.valueOf(s)); } @Override public void afterTextChanged(Editable s) { } }); setCanceledOnTouchOutside(false); } private class ItemClick implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mSelectedItem=(SearchItem)mAdapter.getItem(position); searchview.setText(mSelectedItem.title); search_container.setVisibility(View.INVISIBLE); } } public interface AutoCompleteSearchDialogListener { void OnAcceptClick(SearchItem item); } public String getInput() { return inputContent; } public static class SearchItem{ public String title; public String id; public String position; public String category; public int start;//记录过滤字符串的起点,只在内部使用 public int length;//记录过滤字符串的长度,只在内部使用 @Override public String toString() { return "--@SearchItem--[title--"+title+"--id--"+id+"--position--"+position+"--category--"+category+"--start--"+start+"--length--"+length+"--]"; } } }
public class SearchAutoCompleteAdapter extends BaseAdapter implements Filterable{ private DataFilter mFilter; private Activity activity; private List<AutoCompleteSearchDialog.SearchItem> mDataSource; // 这是原始的数据 private List<AutoCompleteSearchDialog.SearchItem> mFiltData = new ArrayList<AutoCompleteSearchDialog.SearchItem>(); // 过滤之后的数据,这个数据会改变 //设置原始数据源 public void setDataRecord(List<AutoCompleteSearchDialog.SearchItem> list){ mDataSource=list; } public SearchAutoCompleteAdapter(Activity activity,List<AutoCompleteSearchDialog.SearchItem> list){ this.activity=activity; updateData(list); } @Override public int getCount() { return mFiltData.size(); } @Override public Object getItem(int position) {return mFiltData.get(position);} @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder=null; if (null == convertView) { holder=new ViewHolder(); convertView = View.inflate(activity, R.layout.layout_item_auto_complete_search,null); holder.tv= (TextView) convertView.findViewById(R.id.auto_complete_search); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } if(mFiltData.get(position).length>0){ int star=mFiltData.get(position).start; int length=mFiltData.get(position).length; ForegroundColorSpan yellow = new ForegroundColorSpan(Color.rgb(255,102,0)); SpannableString spannablestring=new SpannableString(mFiltData.get(position).title); spannablestring.setSpan(yellow, star, star+length,Spannable.SPAN_INCLUSIVE_INCLUSIVE); holder.tv.setText(spannablestring); }else{ holder.tv.setText(mFiltData.get(position).title); } return convertView; } class ViewHolder{ TextView tv; } @Override public Filter getFilter() { if (mFilter==null) { mFilter = new DataFilter(); } return mFilter; } // 自定义Filter类 class DataFilter extends Filter { @Override // 该方法在子线程中执行 // 自定义过滤规则 protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); List<AutoCompleteSearchDialog.SearchItem> newValues = new ArrayList<AutoCompleteSearchDialog.SearchItem>(); mFiltData.clear(); String filterString = constraint.toString().toLowerCase(); // 如果搜索框内容为空,就恢复原始数据 if (TextUtils.isEmpty(filterString)) { for(AutoCompleteSearchDialog.SearchItem item : mDataSource){ item.start=0; item.length=0; } newValues = mDataSource; } else { // 过滤出新数据 for(int i=0;i<mDataSource.size();i++){ String str=mDataSource.get(i).title; int start=str.toLowerCase().indexOf(filterString); if (-1 != start) { mDataSource.get(i).start=start; mDataSource.get(i).length=filterString.length(); newValues.add(mDataSource.get(i)); }else{ mDataSource.get(i).start=0; mDataSource.get(i).length=0; } } } updateData(newValues); results.values = newValues; results.count = newValues.size(); return results; } @Override protected void publishResults(CharSequence constraint,FilterResults results) { updateData((List<AutoCompleteSearchDialog.SearchItem>)results.values); if (results.count > 0) { notifyDataSetChanged(); // 通知数据发生了改变 } else { notifyDataSetInvalidated(); // 通知数据失效 } } } //不能采用直接赋值的形式,会改变原始数据源。 private void updateData(List<AutoCompleteSearchDialog.SearchItem> list){ mFiltData.clear(); mFiltData.addAll(list); } }