Динамическое обновление адаптера AutoCompleteTextView

Я хочу периодически менять предложения, предоставленные AutoCompleteTextview, получая список из веб-сервиса RESTful и не могу заставить его работать плавно. Я установил жестко запрограммированный список предложений, чтобы убедиться, что он работает:

ArrayAdapter adapter = new ArrayAdapter(this, R.layout.list_item, new String[] {"Hi", "Ho"}); speciesName.setAdapter(adapter);//my autocomplete tv 

У меня есть TextWatcher в текстовом режиме, и когда текст изменяется, который запускает неблокирующий вызов, чтобы получить новый список предложений – эта часть, которая получает новый список, работает нормально. Затем я хочу сбросить адаптер так:

 public void setOptionsAndUpdate(String[] options) { Log.d(TAG, "setting options"); //speciesName.setAdapter((ArrayAdapter)null); ArrayAdapter adapter = new ArrayAdapter(this, R.layout.list_item, options); speciesName.setAdapter(adapter); } 

Этот метод вызывается, но не работает – список предложений исчезает или отображаемые предложения остаются неизменными, несмотря на вызов setAdapter .

Это даже правильный подход? Я посмотрел на SimpleCursorAdapter но не смог узнать, как зарегистрировать мой веб-сервис в качестве поставщика контента. (Он имеет форму http://www.blah.com/query?term=XX , где XX – это вход из моего приложения, и ответ представляет собой массив строк JSON.)

Вот как я обновляю свой AutoCompleteTextView:

 String[] data = terms.toArray(new String[terms.size()]); // terms is a List ArrayAdapter adapter = new ArrayAdapter(activity, android.R.layout.simple_dropdown_item_1line, data); keywordField.setAdapter(adapter); // keywordField is a AutoCompleteTextView if(terms.size() < 40) keywordField.setThreshold(1); else keywordField.setThreshold(2); 

Теперь, конечно, это статично и не имеет дело с предложениями по поводу эфира, но я также могу предложить вам уведомить адаптер об изменениях после того, как вы назначили его автозагрузчику AutoCompleteTextView:

 adapter.notifyDataSetChanged(); 

Надеюсь это поможет.

-serkan

Мне не повезло с помощью adapter.notifyDataSetChanged () при динамическом добавлении и изменении данных в адаптере. В моей ситуации я асинхронно удалял внешний api и периодически получал список данных завершения.

Этот код очищает адаптер и добавляет новые данные, как вы ожидали. Однако мне пришлось вызвать метод getFilter (). Метод фильтра, чтобы заставить данные отображаться. Кроме того, я должен был явно фильтровать на основе текущего текста в AutocompleteTextView, потому что мой api-вызов был асинхронным.

 adapter.clear(); for (Map map : completions) { adapter.add(map.get("name")); } //Force the adapter to filter itself, necessary to show new data. //Filter based on the current text because api call is asynchronous. adapter.getFilter().filter(autocompleteTextView.getText(), null); 

В этом разделе было довольно хорошее руководство по использованию удаленных данных в API Google Map для заполнения AutoCompleteTextView.

Если вам нужна кешированная версия, я получил ее отсюда . Исходный учебник был удален, но по существу вам нужно написать ArrayAdapter с настраиваемым фильтром аналогично тому, как показано ниже, и назначить его вашему автозаполнению.

Примечание. Вам необходимо реализовать метод autocomplete (), который выполняет любую операцию, требуемую для синхронного извлечения и возврата элементов автозаполнения. Поскольку фильтр вызывается в фоновом streamе, это не будет блокировать основной stream пользовательского интерфейса.

 private class PlacesAutoCompleteAdapter extends ArrayAdapter implements Filterable { private ArrayList resultList; public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); } @Override public int getCount() { return resultList.size(); } @Override public String getItem(int index) { return resultList.get(index); } @Override public Filter getFilter() { Filter filter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); if (constraint != null) { // Retrieve the autocomplete results. resultList = autocomplete(constraint.toString()); // Assign the data to the FilterResults filterResults.values = resultList; filterResults.count = resultList.size(); } return filterResults; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { if (results != null && results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } }}; return filter; } } 

Поскольку я не могу добавить комментарий, я даю новый ответ. Нет необходимости в очистке адаптера или вызове adapter.getFilter (). Filter (…) … Чтобы динамически обновлять адаптер AutoCompleteTextView, просто добавьте новый элемент адаптера и setAdapter снова. Для примера, приведенного в исходном вопросе, я пробовал следующее, и он работает (код ниже не показывает начальную настройку адаптера, так как здесь многократные ответы. Это просто показывает обновление адаптера динамически). Обновление адаптера может быть рядом с кодом, который обновляет список, связанный с ArrayAdapter.

  adapter.add(String newSuggestion); // this goes inside a loop for adding multiple suggestions speciesName.setAdapter(adapter) ; // speciesName is an AutoCompleteTextView as given in the original question. 

Лучшее решение, которое я нашел для обновления адаптера:

 Editable text = autocomplete.getText(); autocomplete.setText(text); autocomplete.setSelection(text.length()); 

Как это работает:

Мы устанавливаем текст autoCompleteTextView с его текущим текстом, поэтому адаптер уведомляет, что данные изменены и обновляет содержимое listViews.

Но этим трюком курсор перемещается в начало edittext. поэтому мы используем autocomplete.setSelection(text.length()) для перемещения курсора до конца.

Работает как шарм!

Редактировать:

Также вы должны использовать методы clear() , add() и remove() непосредственно на ArrayAdapter вместо ArrayList .

  • В чем разница между системными приложениями и привилегированными приложениями на Android?
  • Пользовательские макеты уведомлений и цвета текста
  • Как вы устанавливаете frameworks Google (Play, Accounts и т. Д.) На виртуальном устройстве Genymotion?
  • Список всех образов камеры в Android
  • ArrayAdapter в android для создания простого списка
  • VideoView не воспроизводится Видео из желаемой позиции
  • Разрешение Android INJECT_EVENTS
  • Android Studio - как изменить путь к SDK Android
  • Как отправить объект из одной активности Android в другой с помощью намерений?
  • Как реализовать onBackPressed () & intents в fragmentе?
  • Полная веб-страница и отключенный метадатчик view viewport для всех мобильных браузеров
  • Давайте будем гением компьютера.