问题
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:
- autocomplete works well for simple
ArrayList
, all data filtered correct onItemClick
event fires properly after clickparent.getItemAtPosition(position)
returns correctString
representation of the clicked item
The 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:
- How to handle
HashMaps
orCollections
inAutoCompleteTextView
- How to get the right
itemId
in theonItemClick
event
I did very extensive research on this issue, but did not find any valuable information which would answer my questions.
回答1:
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.
回答2:
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;
}
}
回答3:
Implement onItemClickListener for AutoCompleteTextView, then use indexOf on your list to find the index of selected item.
actvCity.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
int index = cityNames.indexOf(actvCity.getText().toString());
// Do Whatever you want to do ;)
}
});
回答4:
First add your data into custom arraylist
// mList used for adding custom data into your model
private List<OutletListSRModel> mList = new ArrayList<>();
// listdata used for adding string data for auto completing.
ArrayList<String> listdata = new ArrayList<String>();
for (int i = 0; i < JArray.length(); i++) {
JSONObject responseJson = JArray.getJSONObject(i);
OutletListSRModel mModel = new OutletListSRModel();
mModel.setId(responseJson.getString("id"));
mModel.name(responseJson.getString("outlet_name"));
listdata.add(responseJson.getString("outlet_name"));
}
ArrayAdapter adapter = new
ArrayAdapter(getActivity(),
android.R.layout.simple_list_item_1, listdata);
searchOutletKey.setAdapter(adapter);
Now for getting any value from model which we added above. we can get like this.
searchOutletKey.setOnItemClickListener ( new AdapterView.OnItemClickListener ( ) {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String txtOutletId = mOutletListSRModel.get(position).getId();
}
});
来源:https://stackoverflow.com/questions/11522592/how-to-get-correct-id-of-autocompletetextview-adapter