I am new to Android development and I ran into a problem which I find difficult to solve. I am trying to figure out how to use an AutoCompleteTextView
widget properly. I want to create a AutoCompleteTextView
, using XML data from a web service. I managed to get it to work, but I am defenitely not pleased with the output.
I would like to put a HashMap
with id => name pairs into the AutoCompleteTextView and get the id of the clicked item. When I click on the autocomplete filtered set output, I want to populate a list underneath the autocompletion box, which I also managed to get to work.
Done so far:
ArrayList
, all data filtered
correctonItemClick
event fires properly after clickparent.getItemAtPosition(position)
returns correct String
representation of the clicked itemThe event onItemClick(AdapterView parent, View v, int position, long id)
does not behave as I would like. How can I figure out the unfiltered array position of the clicked item? The position of the filtered one is the one I am not interested in.
Further questions:
HashMaps
or Collections
in AutoCompleteTextView
itemId
in the onItemClick
eventI did very extensive research on this issue, but did not find any valuable information which would answer my questions.
The event onItemClick(AdapterView parent, View v, int position, long id) does not behave as I would like.
This is a normal situation when filtering an adapter. Although the adapter keeps a reference to the initial unfiltered data from its point of view it has a single set of data on which is based(no matter if is the initial one or resulted from a filter operation). But this shouldn't raise any problems. With the default sdk adapters(or with a subclass), in the onItemClick()
you get the position
for the current list on which the adapter is based. You could then use getItem()
to get data item for that position
(again it doesn't matter if initial or filtered).
String data = getItem(position);
int realPosition = list.indexOf(data); // if you want to know the unfiltered position
this will work for lists and Maps
(assuming that you use the SimpleAdapter
). And for a Maps
you always have the option of adding an additional key to set the unfiltered position in the initial list.
If you use your own adapter along with an AutoCompleteTextView
you could make the onItemClick()
give you the right id
(the position however you can't change).
public class SpecialAutoComplete extends AutoCompleteTextView {
public SpecialAutoComplete(Context context) {
super(context);
}
@Override
public void onFilterComplete(int count) {
// this will be called when the adapter finished the filter
// operation and it notifies the AutoCompleteTextView
long[] realIds = new long[count]; // this will hold the real ids from our maps
for (int i = 0; i < count; i++) {
final HashMap<String, String> item = (HashMap<String, String>) getAdapter()
.getItem(i);
realIds[i] = Long.valueOf(item.get("id")); // get the ids from the filtered items
}
// update the adapter with the real ids so it has the proper data
((SimpleAdapterExtension) getAdapter()).setRealIds(realIds);
super.onFilterComplete(count);
}
}
and the adapter:
public class SimpleAdapterExtension extends SimpleAdapter {
private List<? extends Map<String, String>> mData;
private long[] mCurrentIds;
public SimpleAdapterExtension(Context context,
List<? extends Map<String, String>> data, int resource,
String[] from, int[] to) {
super(context, data, resource, from, to);
mData = data;
}
@Override
public long getItemId(int position) {
// this will be used to get the id provided to the onItemClick callback
return mCurrentIds[position];
}
@Override
public boolean hasStableIds() {
return true;
}
public void setRealIds(long[] realIds) {
mCurrentIds = realIds;
}
}
If you also implement the Filter
class for the adapter then you could get the ids from there without the need to override the AutoCompleTextView
class.
Using the Luksprog approach, I made some similar with ArrayAdapter.
public class SimpleAutoCompleteAdapter extends ArrayAdapter<String>{
private String[] mData;
private int[] mCurrentIds;
public SimpleAutoCompleteAdapter(Context context, int textViewResourceId,
String[] objects) {
super(context, textViewResourceId, objects);
mData=objects;
}
@Override
public long getItemId(int position) {
String data = getItem(position);
int index = Arrays.asList(mData).indexOf(data);
/*
* Atention , if your list has more that one same String , you have to improve here
*/
// this will be used to get the id provided to the onItemClick callback
if (index>0)
return (long)mCurrentIds[index];
else return 0;
}
@Override
public boolean hasStableIds() {
return true;
}
public void setRealIds(int[] realIds) {
mCurrentIds = realIds;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With