Как обрабатывать HashMaps или коллекции в AutoCompleteTextView
Вы можете установить свой собственный адаптер. В вашем адаптере это зависит от вас, где вы получите свои данные в данной позиции.
Как получить правильный itemId в событии onItemClick
В своем настраиваемом адаптере вы определяете фильтр, и этот фильтр устанавливает предлагаемые элементы. У вас есть два разных списка, один с исходными значениями, а другой с отфильтрованными элементами. Я имею в виду что-то вроде этого.
private class AutoCompleteItemAdapter extends ArrayAdapter<YourItemClass> implements Filterable {
private NameFilter mFilter;
List<YourItemClass> suggestions;
List<YourItemClass> mOriginalValues;
public AutoCompleteItemAdapter(Context context, int resource, List<YourItemClass> suggestions) {
super(context, resource, suggestions);
this.suggestions = suggestions;
this.mOriginalValues = suggestions;
}
public void updateData(List<YourItemClass> suggestions) {
mLock.lock();
try{
this.suggestions = suggestions;
this.mOriginalValues = suggestions;
finally{
mLock.unlock();
}
}
@Override
public int getCount() {
mLock.lock();
try {
return suggestions.size();
} finally {
mLock.unlock();
}
}
@Override
public YourItemClass getItem(int position) {
return mOriginalValues.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// draw your item here...
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new NameFilter();
}
return mFilter;
}
private class NameFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
mLock.lock();
try {
mOriginalValues = new ArrayList<YourItemClass>(suggestions);
} finally {
mLock.unlock();
}
}
if (prefix == null || prefix.length() == 0) {
mLock.lock();
try {
ArrayList<YourItemClass> list = new ArrayList<YourItemClass>(mOriginalValues);
results.values = list;
results.count = list.size();
} finally {
mLock.unlock();
}
} else {
String prefixString = prefix.toString().toLowerCase();
final List<YourItemClass> values = mOriginalValues;
final int count = values.size();
final ArrayList<YourItemClass> newValues = new ArrayList<YourItemClass>(count);
// FILTERING
//
// add your hits to the newValues collection
//
//
results.values = newValues;
results.count = newValues.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mLock.lock();
try {
if (results == null || results.values == null) return;
suggestions = new ArrayList<YourItemClass>();
suggestions = (List<YourItemClass>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
} finally {
mLock.unlock();
}
}
}
}
Теперь это может вызвать некоторые проблемы с параллелизмом, как мы уже упоминали, адаптер может запросить размер списка и вывести большее значение, что может вызвать проблемы в функции getView. (fi .: Попытка нарисовать 5 элементов с базовыми данными имеет только 4, потому что мы сделали другую фильтрацию) Таким образом, мы использовали AutoCompleteTextView
, и пока он работает отлично, нет проблем. Я только что упомянул, что я все еще обеспокоен, и у меня есть смутное ощущение, что есть лучшее решение для этого.
В прослушивателе onClick вы используете возвращенное значение (из отфильтрованного списка) в качестве ключа на карте и получаете соответствующее значение. Вы можете думать, что ваш список вы используете индекс для HashMap
. После этого вы можете использовать Map
, чтобы нарисовать свой элемент или получить свои собственные данные.