问题
Hello I'm having problems understanding how the ArrayAdapter works. My code is working but I dont know how.(http://amy-mac.com/images/2013/code_meme.jpg)
I have my activity, inside it i have 2 private classes.:
public class MainActivity extends Activity {
...
private void SomePrivateMethod(){
autoCompleteTextView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, new ArrayList<String>(Arrays.asList(""))));
autoCompleteTextView.addTextChangedListener(new MyTextWatcher());
}
...
private class MyTextWatcher implements TextWatcher {
...
}
private class SearchAddressTask extends AsyncTask<String, Void, String[]> {
...
}
}
Now inside my textwatcher class i call the search address task:
@Override
public void afterTextChanged(Editable s) {
new SearchAddressTask().execute(s.toString());
}
So far so good.
In my SearchAddressTask I do some stuff on doInBackground() that returns the right array.
On the onPostExecute() method i try to just modify the AutoCompleteTextView adapter to add the values from the array obtained in doInBackground() but the adapter cannot be modified:
NOT WORKING CODE:
protected void onPostExecute(String[] addressArray) {
ArrayAdapter<String> adapter = (ArrayAdapter<String>) autoCompleteDestination.getAdapter();
adapter.clear();
adapter.addAll(new ArrayList<String>(Arrays.asList(addressArray)));
adapter.notifyDataSetChanged();
Log.d("SearchAddressTask", "adapter isEmpty : " + adapter.isEmpty()); // Returns true!!??!
}
I dont get why this is not working. Even if i run it on UI Thread...
I kept investigating, if i recreate the arrayAdapter, is working in the UI (Showing the suggestions), but i still need to clear the old adapter:
WORKING CODE:
protected void onPostExecute(String[] addressArray) {
ArrayAdapter<String> adapter = (ArrayAdapter<String>) autoCompleteDestination.getAdapter();
adapter.clear();
autoCompleteDestination.setAdapter(new ArrayAdapter<String>(NewDestinationActivity.this,android.R.layout.simple_spinner_dropdown_item, new ArrayList<String>(Arrays.asList(addressArray))));
//adapter.notifyDataSetChanged(); // no needed
Log.d("SearchAddressTask", "adapter isEmpty : " + adapter.isEmpty()); // keeps returning true!!??!
}
So my question is, what is really happening with this ArrayAdapter? why I cannot modify it in my onPostExecute()? Why is working in the UI if i am recreating the adapter? and why i need to clear the old adapter then?
I dont know there are so many questions that I need some help in here!!
Thanks!!
回答1:
I followed the recomendation of pskink, Thanks a lot!!
I switched all the responsability to the ArrayAdapter and implemented my own as filter.
import java.util.ArrayList;
import android.content.Context;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import com.roisoftstudio.travelalarm.gui.utils.StreetListHelper;
public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> mData;
private Context context;
public AutoCompleteAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.context = context;
mData = new ArrayList<String>();
}
@Override
public int getCount() {
return mData.size();
}
@Override
public String getItem(int index) {
return mData.get(index);
}
@Override
public Filter getFilter() {
Filter myFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
mData = StreetListHelper.getStreetList(context, constraint.toString());
filterResults.values = mData;
filterResults.count = mData.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
}
};
return myFilter;
}
}
来源:https://stackoverflow.com/questions/24096851/arrayadapter-need-to-be-clear-even-i-am-creating-a-new-one