Android, función add () de ArrayAdapter no funciona

Tengo un ArrayAdapter (myAdapter) atado a un componente de AutoCompleteTextView (textView).
Una vez que el usuario pulsa un carácter me gustaría rellenar la lista desplegable de AutoCompleteTextView con elementos que contienen este carácter.
Recupero los elementos usando AsyncTask (que utiliza un servicio web).

Llamo myAdapter.add (item) pero la lista desplegable está vacía.
He añadido una llamada myAdapter.getCount () después de cada adición y muestra cero cada vez. Llamar notifyDataSetChanged () no ayudó.
Incluso traté de agregar objetos String simple en lugar de mis objetos personalizados, sin éxito.
¿Qué estoy haciendo mal?

Edit: He cambiado el código como miette sugirió a continuación, pero todavía en vano.
Generalmente, lo que hago es después de que el texto se cambie en mi vista completa de texto automático, llamo a un AsyncTask nuevo y le paso el texto introducido y un manejador (vea afterTextChanged ()). La tarea recupera los objetos relevantes para el texto y una vez hecho se maneja el Handler's handleMessage (). En handleMessage () intento rellenar los objetos del adaptador. Sin embargo, la lista desplegable del adaptador termina vacía.

Aquí está mi código:

public class AddStockView extends Activity implements OnClickListener, OnItemClickListener, TextWatcher { ArrayAdapter<Stock> adapter; AutoCompleteTextView textView; Vector<Stock> stocks; public AddStockView() { // TODO Auto-generated constructor stub stocks = new Vector<Stock>(); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.add_stock_view); findViewById(R.id.abort_button).setOnClickListener(this); adapter = new ArrayAdapter<Stock>(this, android.R.layout.simple_dropdown_item_1line, stocks); //adapter.setNotifyOnChange(true); textView = (AutoCompleteTextView) findViewById(R.id.search_edit_text); textView.setAdapter(adapter); textView.setOnItemClickListener(this); textView.addTextChangedListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.abort_button: finish(); break; case R.id.search_edit_text: break; } } @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // TODO Auto-generated method stub Stock stockToAdd = (Stock)parent.getAdapter().getItem(position); //TODO: Add the above stock to user's stocks and close this screen finish(); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.layout.menu, menu); CategoryMenu.getInstance().populateMenu(menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { CategoryMenu.getInstance().menuItemSelected(item, this); return false; } @Override public boolean onPrepareOptionsMenu(Menu menu) { return true; } @Override public void afterTextChanged(Editable text) { // TODO Auto-generated method stub if (text.toString().equals("")) return; new AppTask().execute(new AppTask.Payload(Consts.taskType.SEARCH_STOCK, new Object[] {text, handler}, this)); } @Override public void beforeTextChanged(CharSequence a0, int a1, int a2, int a3) { // TODO Auto-generated method stub } @Override public void onTextChanged(CharSequence a0, int a1, int a2, int a3) { // TODO Auto-generated method stub } private void addStockItemsToAdapter(Vector<Object> dataItems) { for (int i = 0; i <dataItems.size(); i++) { Stock stk = (Stock)dataItems.elementAt(i); stocks.add(stk); } } public void populateAdapter() { addStockItemsToAdapter(ContentReader.getInstance.getDataItems()); adapter.notifyDataSetChanged(); int size = adapter.getCount(); // size == 0 STILL!!!! textView.showDropDown(); } final Handler handler = new Handler() { public void handleMessage(Message msg) { populateAdapter(); } }; } 

Muchas gracias, Rob

¿Dónde llamas addItemsToAdapter ()? ¿Puede mostrarnos, cómo ha intentado agregar cadenas simples a su adaptador?

Editar: fuera de los comentarios el ejemplo de código útil:

 adapter = new ArrayAdapter<Stock>(this, android.R.layout.simple_dropdown_item_1line, stocks); adapter.notifyDataSetChanged(); textView.setAdapter(adapter); 

Tuve el mismo problema. Después de examinar el código fuente ArrayAdapter y AutoCompleteTextView, descubrí que el problema era, en resumen, que:

  • La lista de objetos original se almacena en ArrayAdapter.mObjects .
  • Sin embargo, AutoCompleteTextView habilita el filtrado de ArrayAdapter , lo que significa que se agregan nuevos objetos a ArrayAdapter.mOriginalValues , mientras que mObjects contiene los objetos filtrados.
  • ArrayAdapter.getCount() devuelve siempre el tamaño de mObjects .

Mi solución fue anular ArrayAdapter.getFilter() para devolver un filtro que no filtra. De esta manera mOriginalValues es null y mObjects se utiliza en su lugar en todos los casos.

Código de muestra:

 public class MyAdapter extends ArrayAdapter<String> { NoFilter noFilter; /* ... */ /** * Override ArrayAdapter.getFilter() to return our own filtering. */ public Filter getFilter() { if (noFilter == null) { noFilter = new NoFilter(); } return noFilter; } /** * Class which does not perform any filtering. * Filtering is already done by the web service when asking for the list, * so there is no need to do any more as well. * This way, ArrayAdapter.mOriginalValues is not used when calling eg * ArrayAdapter.add(), but instead ArrayAdapter.mObjects is updated directly * and methods like getCount() return the expected result. */ private class NoFilter extends Filter { protected FilterResults performFiltering(CharSequence prefix) { return new FilterResults(); } protected void publishResults(CharSequence constraint, FilterResults results) { // Do nothing } } } 

Cree un adaptador de matriz con un vector o una matriz como:

 ArrayAdapter(Context context, int textViewResourceId, T[] objects) 

Al inicializar su arrayadapter, lo hará escuchar array de objetos. No agregue el artículo al adaptador ni borre el adaptador, haga sus adiciones en "objetos" arsenal y también límpielo. Después de los cambios en esta llamada del arreglo

 adapter.notifyDataSetChanged(); 

Más específicamente

 ArrayAdapter<YourContentType> yourAdapter = new ArrayAdapter<YourContentType> (this,R.id.OneOfYourTextViews,YourDataList); yourAdapter.notifyDataSetChanged(); aTextView.setText(yourAdapter.isEmpty() ? "List is empty" : "I have too many objects:)"); 

Esto debe hacerse después de cargar YourDataList, he comprobado su código, ¿está seguro que el manejador llama addStockItemsToAdapter() antes de buscar su adaptador está vacío o no? También debe comprobar si el vector de existencias tiene algún elemento en él.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.