I've been googling my ass of trying to find someone that are having the same problem as me, without luck. So here's my problem:
I'm trying to implement a autocomplete suggestion of addresses as the user types the name of a place using the geocoder in Android. I want this to behave much the same as the javascript version using a combbox.
I am using a layout with an AutoCompleteTextView, and an arrayadapter to dynamically update the suggestionlist as the user types. I have added a 500ms delay from when the onTextChanged() event is received before a call to the geocoder.getFromLocationName is called using a Handler. If a user types more letter within 500ms, the last event will be cancelled. The problem I am encountering is that the suggestions almost never show up in the UI as selectables in the dropdown. I get the address suggestions, but when I add them to the adapter attached to the autocomplatetextview they simple wont show.
I'm running this on an emulator using API level 7, with google apis included.
Now some source code to aid you: The layout:
<LinearLayout android:id="@+id/searchInputLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="6dip"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/searchMessage" />
<EditText android:id="@+id/freetextInput"
android:hint="@string/searchFreetextLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background" />
<CheckBox android:id="@+id/includeVincinityCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/includeVincinityLabel"
android:checked="true"
android:onClick="includeVincinityClick" />
<AutoCompleteTextView android:id="@+id/locationInput"
android:hint="@string/locationInputHint"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button android:id="@+id/searchButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/searchBtnLabel"
android:onClick="searchBtnClicked" />
</LinearLayout>
The source code of my activity (I've omitted code not relevant):
public class SearchLocationTabActivity extends Activity implements TextWatcher, OnItemSelectedListener {
private static final int MESSAGE_TEXT_CHANGED = 0;
private static final int AUTOCOMPLETE_DELAY = 500;
private static final int THRESHOLD = 3;
private String latitude, longitude;
private List<Address> autoCompleteSuggestionAddresses;
private ArrayAdapter<String> autoCompleteAdapter;
private Handler messageHandler;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.search);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
messageHandler = new MyMessageHandler(this, this);
autoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, new ArrayList<String>());
autoCompleteAdapter.setNotifyOnChange(false);
AutoCompleteTextView locationinput = (AutoCompleteTextView) findViewById(R.id.locationInput);
locationinput.addTextChangedListener(this);
locationinput.setOnItemSelectedListener(this);
locationinput.setThreshold(THRESHOLD);
locationinput.setAdapter(autoCompleteAdapter);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
messageHandler.removeMessages(MESSAGE_TEXT_CHANGED);
}
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
String value = arg0.toString();
if (!"".equals(value) && value.length() >= THRESHOLD) {
Message msg = Message.obtain(messageHandler, MESSAGE_TEXT_CHANGED, arg0.toString());
messageHandler.sendMessageDelayed(msg, AUTOCOMPLETE_DELAY);
} else {
autoCompleteAdapter.clear();
}
}
@Override
public void afterTextChanged(Editable arg0) {
}
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if (arg2 < autoCompleteSuggestionAddresses.size()) {
Address selected = autoCompleteSuggestionAddresses.get(arg2);
latitude = Double.toString(selected.getLatitude());
longitude = Double.toString(selected.getLongitude());
}
}
private void notifyResult(List<Address> suggestions) {
latitude = longitude = null;
autoCompleteAdapter.clear();
for (Address a : autoCompleteSuggestionAddresses) {
autoCompleteAdapter.add(a.toString());//TODO: figure out a nice way to display this address in list
}
autoCompleteAdapter.notifyDataSetChanged();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
latitude = longitude = null;
}
private class MyMessageHandler extends Handler {
private Context context;
private AsyncTaskSubscriber subscriber;
public MyMessageHandler(Context context, AsyncTaskSubscriber subscriber) {
this.context = context;
this.subscriber = subscriber;
}
@Override
public void handleMessage(Message msg) {
if (msg.what == MESSAGE_TEXT_CHANGED) {
String enteredText = (String) msg.obj;
try {
autoCompleteSuggestionAddresses = new Geocoder(context).getFromLocationName(enteredText, 10);
notifyResult(response);
} catch (IOException ex) {
Log.e(GeoCoderAsyncTask.class.getName(), "Failed to get autocomplete suggestions", ex);
}
}
}
}
}
Any help is much appreciated!