开箱即用,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