AutoCompleteTextView で HashMaps または Collections を処理する方法
独自のカスタム アダプターを設定できます。アダプターでは、データを特定の位置に配置する場所はあなた次第です。
onItemClick イベントで正しい itemId を取得する方法
カスタム アダプタでフィルタを定義すると、そのフィルタによって提案されたアイテムが設定されます。2 つの異なるリストがあり、1 つは元の値を含み、もう 1 つはフィルター処理されたアイテムを含みます。私はこのようなことを意味します。
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 関数で問題が発生する可能性があります。(図: 基になるデータで 5 つの要素を描画しようとすると、別のフィルタリングを行ったため、4 つしかありません) これは を使用した方法AutoCompleteTextView
であり、これまでのところうまく機能し、問題ありません。私はまだ心配していると言いましたが、これにはもっと良い解決策があると漠然と感じています.
onClick リスナーでは、返された値 (フィルタリングされたリストから) をマップのキーとして使用し、関連付けられた値を取得します。のインデックスを使用するリストを考えることができますHashMap
。その後、 を使用Map
してアイテムを描画したり、独自のデータを取得したりできます。