Reputation: 197
I manage an AutoCompleteTextView
that should give all the towns (ville) found in my DB, according the 4 first letters I put in.
The Async task
works well and gets the right data.
My problem is that the DropDownList
display NOT all the items. Often only 1, 2, 3 or 4 out of the 20 returned by the DB.
So I figured out, there should be some auto filtering within the ACTV itself! I check many topics here on SO, to update my code but I didn't succeed.... :-(
I keep getting errors without knowing exactly what the trouble is! :-(
So here is my code:
class MyActivity extends Activity implements AdapterView.OnItemClickListener
{
static class Ville
{
String id;
String name;
@Override
public String toString() { return this.name; }
};
ArrayAdapter<Ville> villeAdapter;
String villeAdapterFilter;
VilleUpdateTask villeAdapterUpdateTask;
AutoCompleteTextView villeText;
Ville selectedVille;
final TextWatcher textChecker = new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
MyActivity.this.setAdapterFilter(s.toString());
}
};
public void onCreate(Bundle bundle)
{
super.onCreate(bundle);
setContentView(R.layout.main);
this.villeAdapter = new ArrayAdapter<Ville>(this,android.R.layout.simple_dropdown_item_1line, new Ville[0]);
this.villeText = (AutoCompleteTextView ) findViewById(R.id.villeSelector);
this.villeText.setAdapter(this.villeAdapter);
this.villeText.setThreshold(THRESHOLD_DROPDOWN);
this.villeText.setOnItemClickListener(this);
this.villeText.addTextChangedListener(textChecker);
}
public void onDestroy() { stopVilleAdapterUpdate();
public void setAdapterFilter(String filter)
{
if (filter == null) {
// clearing the adapter
this.villeAdapterFilter = null;
this.villeAdapter.clear();
this.villeAdapter.notifyDataSetChanged();
Log.d("MyActivity","Clearing ville filter !");
} else if (filter.length() > THRESHOLD_QUERY) {
if (this.villeAdapterFilter == null) {
Log.d("MyActivity","Ville Adapter Filter defined to:"+filter);
this.villeAdapterFilter = filter;
startVilleAdapterUpdate();
} else {
Log.d("MyActivity","Already filtered with:"+this.villeAdapterFilter);
}
} else {
Log.d("MyActivity","Resetting filter (not enough data)");
this.villeAdapterFilter = null;
this.villeAdapter.clear();
this.villeAdapter.notifyDataSetChanged();
}
}
public synchronized void onItemClick(ViewAdapter<?> ad, View v, int position, long id)
{
this.selectedVille = this.villeAdapter.getItemAtPosition(position);
Log.d("MyActivity","Ville selected: "+this.selectedVille);
}
public synchronized void startVilleAdapterUpdate()
{
stopVilleAdapterUpdate();
Log.d("MyActivity","Starting Update of Villes with "+this.villeAdapterFilter);
this.villeAdapterUpdateTask = new VilleUpdateTask();
this.villeAdapterUpdateTask.execute(this.villeAdapterFilter);
}
public synchronized void stopVilleAdapterUpdate()
{
if (this.villeAdapterUpdateTask != null) {
Log.d("MyActivity","Stopping current update of villes");
this.villeAdapterUpdateTask.cancel(true);
this.villeAdapterUpdateTask = null;
}
}
public synchronized void onVilleAdapterUpdateResult(Ville[] data)
{
this.villeAdapterUpdateTask = null;
if (data != null) {
Log.d("MyActivity","Received "+data.length+" villes from update task");
this.villeAdapter.clear();
this.villeAdapter.addAll(data);
this.villeAdapter.notifyDataSetChanged(); // mise à jour du drop down...
}
}
class VilleUpdateTask extends AsyncTask<String,Void,Ville[]>
{
public Ville[] doInBackground(String ... filters)
{
ArrayList<Ville> values = new ArrayList<Ville>();
try {
HttpClient httpclient = new DefaultHttpClient();
....
....
for(int i=0;i<json_array.length();i++) {
JSONObject json_ligne = json_array.getJSONObject(i);
try {
Ville v = new Ville();
v.name = json_ligne.getString("NAME_VILLE");
v.id = json_ligne.getString("ID_VILLE");
values.add(v);
} catch (Exception ex) {
Log.w("VilleUpdateTask","Invalid value for Ville at index #"+i,ex);
}
}
} catch (Exception ex) {
Log.e("VilleUpdateTask","Failed to retrieve list of Ville !",ex);
}
return values.toArray(new Ville[values.size()]);
}
public void onPostExecute(Ville[] data)
{
MyActivity.this.onVilleAdapterUpdateResult(data);
}
}
}
EDIT 1: yep sorry, my ACTV is a basic TextView, it is not a scrolling problem because on better case I can see 10 items in the list, and last the position is random
EDIT 2: could you just help me to adapt my existing code to the given solutions from the 2 URLs above?
(1) according to that solution AutoCompleteTextView - disable filtering
I have to:
create my class ClassMyACArrayAdapter which is the same as the given one, only its name changes
change my declaration from
ArrayAdapter villeAdapter;
to
List<ClassMyACArrayAdapter> villeAdapter;
but in the onCreate what should replace the initial
this.villeAdapter = new ArrayAdapter
(this,android.R.layout.simple_dropdown_item_1line, new Ville[0]);
Upvotes: 3
Views: 6057
Reputation: 4855
Just call autoCompleteTextView.showDropDown()
Whenever you need it.....cheers :)
Upvotes: 7
Reputation: 1037
Is your AutoCompleteTextView a TextView, LinearLayout o ListView? The code in your activity looks fine, so I'm guessing that the problem could be in the layout (maybe you're not using a scroll so you can only see the first values).
Also, the values that you see are always the first ones in the returned list or they're at random positions?
Upvotes: 0