Я пытаюсь заставить AutoCompleteTextView (ACTV) отображать результаты, я - получение от сетевого ресурса. Я установил завершение-treshold на 2, и я вижу, что запрос запущен, когда я вхожу в символы.
Результатом, который я получаю, является корректный. Позволяет говорят, что я пишу "приблизительно", и я получаю результат "автомобиль" как автозавершение. У меня есть функция обратного вызова, которая получает результат AsyncTask и помещает результат в ArrayAdapter. Затем я называю .showDropDown () на ACTV, и пустое выпадающее показывают (половина размера нормального элемента). Затем, если я ввожу последнюю букву "r", и ACTV показывает "автомобиль", выпадающее показывают, и результат внезапно находится в списке.
То же происходит, если я ввел два символа (который возвращает допустимый результат), и удаление последней буквы. Когда буква удалена, "автомобиль" показывается значением автозавершения.
У кого-либо была эта проблема? Похоже, что адаптер заполнен результатом, но результат не показывает до следующего действия я делаю. Я также попытался выполнить .notifyDataSetChanged () после того, как я добавил результат к адаптеру, но это не должно быть необходимо, или?
Не видя вашего кода, трудно сказать, что может происходить. Но первое, что приходит в голову, это то, что ваш сетевой запрос выполняется в другом потоке, и поэтому ваш performFiltering ()
может преждевременно возвращать пустой набор результатов. В этот момент publishResults ()
возвращает пустой результат, а раскрывающийся список пуст. Позже ваша AsyncTask вернет свой результат, и вы добавите результаты в список адаптера, но по той или иной причине он еще не отображается.
Я думаю, вы ошибаетесь насчет необходимости AsyncTask. Объект Filter уже выполняет что-то похожее на AsyncTask: performFiltering ()
выполняется в фоновом потоке, а publishResults ()
вызывается из потока пользовательского интерфейса после завершения performFiltering () . Таким образом, вы можете выполнить свой сетевой запрос непосредственно в performFiltering () и установить результаты в объект FilterResults, и вам не придется беспокоиться о том, что сетевой запрос будет слишком медленным и вызовет проблемы в вашем пользовательском интерфейсе.
Альтернативное решение, которое немного сложнее, но это то, что я делаю в своем объекте Filter (из-за существующей архитектуры, которая выполняет вызовы API в фоновом режиме, используя асинхронный обратный вызов вместо блокирующего / синхронного шага по мере необходимости. для performFiltering ()) заключается в использовании синхронизированного объекта с wait () / notify () для выполнения межпоточного мониторинга, поэтому эффект такой же, как при выполнении сетевого запроса непосредственно в performFiltering (), но на самом деле это происходит в нескольких thread:
// in Filter class..
protected FilterResults performFiltering(CharSequence constraint) {
APIResult response = synchronizer.waitForAPI(constraint);
// ...
}
// callback invoked after the API call finishes:
public void onAPIComplete(APIResult results) {
synchronizer.notifyAPIDone(results);
}
private class Synchronizer {
APIResult result;
synchronized APIResult waitForAPI(CharSequence constraint) {
someAPIObject.startAsyncNetworkRequest(constraint);
// At this point, control returns here, and the network request is in-progress in a different thread.
try {
// wait() is a Java IPC technique that will block execution until another
// thread calls the same object's notify() method.
wait();
// When we get here, we know that someone else has just called notify()
// on this object, and therefore this.result should be set.
} catch(InterruptedException e) { }
return this.result;
}
synchronized void notifyAPIDone(APIResult result) {
this.result = result;
// API result is received on a different thread, via the API callback.
// notify() will wake up the other calling thread, allowing it to continue
// execution in the performFiltering() method, as usual.
notify();
}
}
Однако я думаю, что вы можете обнаружить, что самое простое решение - это просто синхронно выполнять сетевой запрос непосредственно в методе performFiltering (). Приведенный выше пример кода является лишь одной из возможностей, если у вас уже есть архитектура для асинхронных / управляемых обратным вызовом API-вызовов, и вы не хотите изменять это поведение, чтобы получить синхронные результаты в performFiltering ().