У меня есть собственный адаптер, который используется для фильтрации результатов поиска. Это отлично работает для поиска тегов автозаполнения поиска. Однако он был изменен, чтобы отображать недавно найденные элементы, когда пользователь впервые прикасается к текстовому представлению поиска. Процесс фильтрации инициируется установкой текста на "" в текстовом поле поиска:
TextView.OnTouchListener onTouchListener = new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
searchTextView.setText("");
recentSearches = true;
return false;
}
};
Также есть Textwatcher:
TextWatcher onSearchSuggestionTextChanged = 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)
{
if (s.length() > 0)
{
recentSearches = false;
}
}
@Override
public void afterTextChanged(Editable s)
{
if (!recentSearches && s.length() == 0)
{
cancelSearch();
}
}
};
Поиск textView инициализируется следующим образом:
searchTextView.setAdapter(new SearchAdapter(this));
searchTextView.addTextChangedListener(onSearchSuggestionTextChanged);
searchTextView.setOnTouchListener(onTouchListener);
И SearchAdapter:
public class SearchAdapter extends BaseAdapter implements Filterable
{
private Context context;
private List<FoundItem> resultList = new ArrayList<FoundItem>();
private List<FoundItem> recentSearches = null;
public SearchAdapter(Context context)
{
this.context = context;
}
@Override
public int getCount()
{
return resultList.size();
}
@Override
public FoundItem getItem(int index)
{
return resultList.get(index);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.simple_dropdown_item, parent, false);
}
FoundItem item = getItem(position);
((TextView) convertView.findViewById(R.id.text)).setText(item.name());
return convertView;
}
@Override
public Filter getFilter()
{
Filter filter = new Filter()
{
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults filterResults = new FilterResults();
if (constraint != null)
{
List<FoundItem> items = findSuggestions(context, constraint.toString());
// Assign the data to the FilterResults
filterResults.values = items;
filterResults.count = items.size();
}
else
{
filterResults.values = getRecentSearches();
filterResults.count = getRecentSearches().size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
if (results != null && results.count > 0)
{
resultList = (List<FoundItem>) results.values;
notifyDataSetChanged();
}
else
{
notifyDataSetInvalidated();
}
}
};
return filter;
}
private List<FoundItem> findSuggestions(Context context, String query)
{
...
return foundItems;
}
private List<FoundItem> getRecentSearches()
{
...
return recentSearches;
}
Адаптер получает результаты недавних поисков, поэтому методы performFiltering
и publishResults
вызываются, как и ожидалось, но затем один раз вызывается только метод getCount
, и результаты не отображаются. Напротив, элементы автозаполнения отображаются, как и ожидалось, при вводе нескольких символов. Обратите внимание, что недавние поиски не являются нулевыми, и при вызове searchTextView.getAdapter().getCount()
до и после изменения текста возвращается правильное количество предыдущих поисков.
Так почему он не отображает результаты? Любые идеи?
Спасибо