For my AutoCompleteTextView
I need to fetch the data from a webservice. As it can take a little time I do not want UI thread to be not responsive, so I need somehow to fetch the data in a separate thread. For example, while fetching data from SQLite DB, it is very easy done with CursorAdapter
method - runQueryOnBackgroundThread
. I was looking around to other adapters like ArrayAdapter
, BaseAdapter
, but could not find anything similar...
Is there an easy way how to achieve this? I cannot simply use ArrayAdapter
directly, as the suggestions list is dynamic - I always fetch the suggestions list depending on user input, so it cannot be pre-fetched and cached for further use...
If someone could give some tips or examples on this topic - would be great!
With the approach above, i also had those problems when typing very fast. I guess it´s because the filtering of the results is done asynchronously by the filter class, so there can be problems when modifying the ArrayList of the Adapter in the ui thread while filtering is done.
http://developer.android.com/reference/android/widget/Filter.html
However with following approach everything worked fine.
public class MyActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MyAdapter myAdapter = new MyAdapter(this, android.R.layout.simple_dropdown_item_1line);
AutoCompleteTextView acTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
acTextView.setAdapter(myAdapter);
}
}
public class MyAdapter extends ArrayAdapter<MyObject> {
private Filter mFilter;
private List<MyObject> mSubData = new ArrayList<MyObject>();
static int counter=0;
public MyAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
setNotifyOnChange(false);
mFilter = new Filter() {
private int c = ++counter;
private List<MyObject> mData = new ArrayList<MyObject>();
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// This method is called in a worker thread
mData.clear();
FilterResults filterResults = new FilterResults();
if(constraint != null) {
try {
// Here is the method (synchronous) that fetches the data
// from the server
URL url = new URL("...");
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while ((line = rd.readLine()) != null) {
mData.add(new MyObject(line));
}
}
catch(Exception e) {
}
filterResults.values = mData;
filterResults.count = mData.size();
}
return filterResults;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence contraint, FilterResults results) {
if(c == counter) {
mSubData.clear();
if(results != null && results.count > 0) {
ArrayList<MyObject> objects = (ArrayList<MyObject>)results.values;
for (MyObject v : objects)
mSubData.add(v);
notifyDataSetChanged();
}
else {
notifyDataSetInvalidated();
}
}
}
};
}
@Override
public int getCount() {
return mSubData.size();
}
@Override
public MyObject getItem(int index) {
return mSubData.get(index);
}
@Override
public Filter getFilter() {
return mFilter;
}
}
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