android - ArrayAdapter necesita ser claro incluso estoy creando uno nuevo
android-asynctask android-arrayadapter (1)
Hola. Tengo problemas para entender cómo funciona ArrayAdapter. Mi código funciona, pero no sé cómo. ( Http://amy-mac.com/images/2013/code_meme.jpg )
Tengo mi actividad, dentro de ella tengo 2 clases privadas .:
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[]> {
...
}
}
Ahora, dentro de mi clase de observador de textos, llamo a la tarea de dirección de búsqueda:
@Override
public void afterTextChanged(Editable s) {
new SearchAddressTask().execute(s.toString());
}
Hasta aquí todo bien.
En mi SearchAddressTask hago algunas cosas en doInBackground () que devuelve la matriz correcta.
En el método onPostExecute () intento simplemente modificar el adaptador AutoCompleteTextView para agregar los valores de la matriz obtenida en doInBackground () pero el adaptador no se puede modificar:
NO CÓDIGO DE TRABAJO:
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!!??!
}
No entiendo por qué esto no está funcionando. Incluso si lo ejecuto en UI Thread ...
Seguí investigando, si recreé el arrayAdapter, está trabajando en la interfaz de usuario (mostrando las sugerencias), pero aún necesito borrar el viejo adaptador:
CÓDIGO DE TRABAJO:
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!!??!
}
Entonces mi pregunta es, ¿qué está pasando realmente con este ArrayAdapter? ¿Por qué no puedo modificarlo en mi onPostExecute ()? ¿Por qué funciona en la interfaz de usuario si estoy recreando el adaptador? y ¿por qué tengo que borrar el adaptador anterior, entonces?
¡No sé si hay tantas preguntas que necesito ayuda aquí!
¡¡Gracias!!
Seguí la recomendación de pskink, muchas gracias !!
Cambié toda la responsabilidad al ArrayAdapter e implementé el mío como filtro.
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;
}
}