開箱即用,AutoCompleteTextView
小部件似乎無法匹配列表值中間的輸入字符串 - 匹配始終在開始處進行;例如輸入「ar
」匹配「argentina
」,但不匹配「hungary
」。自定義AutoCompleteTextView行爲
如何搜索單詞中間的文字?任何人都可以給我一個想法嗎?
在此先感謝!
開箱即用,AutoCompleteTextView
小部件似乎無法匹配列表值中間的輸入字符串 - 匹配始終在開始處進行;例如輸入「ar
」匹配「argentina
」,但不匹配「hungary
」。自定義AutoCompleteTextView行爲
如何搜索單詞中間的文字?任何人都可以給我一個想法嗎?
在此先感謝!
您需要編寫自定義的Filter
類,並自行實施performFiltering
方法。該方法需要一個CharSequence
參數,您可以使用它來執行任何需要的字符串操作,以便從數據集中生成匹配列表(在您的情況下,可以使用String.contains
而不是String.startsWith
)。 performFiltering
函數不在UI線程上運行。
你再回到你的匹配列表爲FilterResults
對象,其中包含一個Object
值(匹配列表,可能是一個ArrayList
)和int
計數這是您的匹配列表的大小。
最後,實現publishResults
回調方法,該方法在工作線程生成匹配列表後返回,允許您在AutoCompleteTextView的適配器上調用notifyDataSetChanged
,以便它可以顯示結果。
你能給我舉個例子嗎? – Chrishan 2012-01-30 04:22:06
我知道自從這個答案已經有很長的一段時間了,但這是我發現的關於這個主題最準確的一個(也是最難找到的一個,順便說一句)。謝謝! – nKn 2014-01-10 22:07:59
Victor是正確的,下面是簡單的方法:將android.widget.ArrayAdapter的全部內容複製粘貼到一個名爲CustomArrayAdapter的新類中,並通過「contains」更改位於performFiltering和publishResults中的2個「startsWith」事件。簡單。 – 2015-01-06 09:53:23
我的建議是將字符串解析爲字符數組。 然後迭代每個字符,直到找到字符串。
例如讓我們說你的搜索要與他們「吃」字表是......
狀態 特質 痛斥返回所有單詞 晚
你的算法應該是這樣這
採取字符串,並將其解析爲一個字符數組 循環遍歷數組和找到的第一個「正確的字符」(在本例中的「A」) 一旦字符被發現查了N ext字符,繼續檢查每個字符的匹配,直到正在搜索的值完成。如果字符不匹配,則退出數組迭代並轉到下一個單詞。
老問題,但仍然相關。遵循一些其他問題的指導,使用可過濾實現自定義適配器。我製作了一個簡單的通用適配器,用於搜索包含。快速注意事項:
我正在使用butterknife,但很容易用findviewbyid做viewHolder。
佈局R.layout.list_item_simple是一個帶有textview R.id.text_view_simple的簡單佈局。
該對象需要一個toString來進行比較。
public class SimpleContainsAutocompleteAdapter <T> extends ArrayAdapter<T> implements Filterable {
private List <T> listObjects;
List<T> suggestions = new ArrayList<>();
private int resource;
private Filter mFilter = new Filter(){
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint != null) {
suggestions.clear();
for(T object : listObjects){
if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
suggestions.add(object);
}
}
filterResults.values = suggestions;
filterResults.count = suggestions.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence contraint, FilterResults results) {
if(results == null){
return;
}
List<T> filteredList = (List<T>) results.values;
if(results.count > 0) {
clear();
for (T filteredObject : filteredList) {
add(filteredObject);
}
notifyDataSetChanged();
}
}
};
public SimpleContainsAutocompleteAdapter(Context context, List<T> listObjects) {
super(context, R.layout.list_item_simple, listObjects);
this.listObjects = new ArrayList<>(listObjects);
this.resource = R.layout.list_item_simple;
}
@Override
public Filter getFilter() {
return mFilter;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Object listObject = getItem(position);
viewHolder holder;
if(convertView != null) {
holder = (viewHolder) convertView.getTag();
}else{
convertView = LayoutInflater.from(getContext()).inflate(resource, parent, false);
holder = new viewHolder(convertView);
convertView.setTag(holder);
}
holder.name.setText(listObject.toString());
return convertView;
}
static class viewHolder {
@InjectView(R.id.text_view_simple) TextView name;
public viewHolder(View view) {
ButterKnife.inject(this, view);
}
}
}
這是答案,我不得不改變一些東西,但作品完美。 – sdelvalle57 2015-08-25 18:36:42
public class AutoCompleteAdapter <T> extends ArrayAdapter<T> implements Filterable {
private List <T> listObjects;
List<T> suggestions = new ArrayList<>();
private Context context;
public AutoCompleteAdapter(Context context, List<T> listObjects) {
super(context, R.layout.list_item_simple, listObjects);
this.listObjects = new ArrayList<>(listObjects);
this.context = context;
}
private Filter mFilter = new Filter(){
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint != null) {
suggestions.clear();
for(T object : listObjects){
if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){ suggestions.add(object);
}
}
filterResults.values = suggestions;
filterResults.count = suggestions.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results == null){
return;
}
List<T> filteredList = (List<T>) results.values;
if(results.count > 0) {
clear();
for (T filteredObject : filteredList) {
add(filteredObject);
}
notifyDataSetChanged();
}
}
};
@Override
public Filter getFilter() {
return mFilter;
}
private static class ViewHolder {
TextView title;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Object listObject = getItem(position);
final ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_item_simple, parent, false);
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.title.setText(listObject.toString());
return convertView;
}
}
我做類似的東西在這裏! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42 2012-10-29 20:10:58