Управлявам AutoCompleteTextView
, което трябва да даде всички градове (села), намерени в моята база данни, според първите 4 букви, които съм въвел.
Async task
работи добре и получава точните данни.
Проблемът ми е, че DropDownList
показва НЕ всички елементи. Често само 1, 2, 3 или 4 от 20-те, върнати от DB.
Така че разбрах, че трябва да има някакво автоматично филтриране в самия ACTV! Проверявам много теми тук в SO, за да актуализирам кода си, но не успях.... :-(
Продължавам да получавам грешки, без да знам точно какъв е проблемът! :-(
И така, ето моят код:
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);
}
}
}
РЕДАКТИРАНЕ 1: да, съжалявам, моят ACTV е основен TextView, не е проблем при превъртане, защото в по-добър случай мога да видя 10 елемента в списъка, а последната позиция е произволна
РЕДАКТИРАНЕ 2: бихте ли ми помогнали да адаптирам съществуващия си код към дадените решения от 2-та URL адреса по-горе?
(1) според това решение AutoCompleteTextView - деактивиране на филтрирането
Трябва да:
създайте моя клас ClassMyACArrayAdapter, който е същият като дадения, само името му се променя
промяна на моята декларация от
ArrayAdapter villeAdapter;
to
List<ClassMyACArrayAdapter> villeAdapter;
но в onCreate какво трябва да замени първоначалния
this.villeAdapter = нов ArrayAdapter
(this,android.R.layout.simple_dropdown_item_1line, нов Ville[0]);