AutoCompleTeTextView не отображать результат даже при обновлении arrayAdapter
-
28-09-2019 - |
Вопрос
Я пытаюсь получить AutoCompleteTextView (ACTV) для отображения результатов, я получаю от сетевого ресурса. Я установил To Collection-Treshold до 2, и я вижу, что запрос уволен, когда я вхожу в символы.
Результат, который я получаю правильно. Позвольте сказать, я пишу "CA", и я получаю результат «автомобиль» как автозаполнение. У меня есть функция обратного вызова, которая получает результат из асинктрики и ставит результат в arrayAdapter. Затем я звоню .showdropdown () на actv и отображается пустой раскрывающийся друг (половина размера нормального элемента). Тогда, если я вхожу в последнюю букву «R» и ACTV показывает «Car», отображается раскрывающийся список, и результат внезапно в списке.
То же самое происходит, если я вошел в два персонажа (что возвращает действительный результат), а удалить последнюю букву. Когда буква удалена, «автомобиль» отображается как значение автозаполнения.
У кого-нибудь была эта проблема? Похоже, адаптер заполнен результатом, но результат не показывает до следующего действия. Я также пытался запустить .notifydatAsChenged () После того, как я добавил результат к адаптеру, но это не нужно понадобиться, или?
Решение
Не видение вашего кода, трудно сказать, что может происходить. Но первое, что приходит на ум, состоит в том, что ваш сетевой запрос происходит на другой поток, и поэтому ваш performFiltering()
Может возвращать пустой результат, набор преждевременно. В таком случае, publishResults()
возвращает пустой результат, и ваш выпадающий путь пуст. Позже ваша асинктдака получит свой результат назад, и вы добавляете результаты в список адаптера, но по той или иной причине он еще не отображается.
Я думаю, что вы можете ошибаться о необходимости асинктики. Объект фильтра уже делает что-то похожее на асинктику: performFiltering()
сделано в фоновом потоке, а также publishResults()
вызывается из потока пользовательского интерфейса после выполнения (). Таким образом, вы можете выполнить свой запрос сети непосредственно в PerformingFiltering () и установить результаты в объект FilterResults, и вам не придется беспокоиться о сетевом запросе, который является слишком медленным и вызывает проблемы в вашем интерфейсе UI.
Альтернативное решение, которое немного сложнее, но это то, что я делаю в своем объекте фильтра (из-за существующей архитектуры, которая делает вызовы API в фоновом режиме, используя асинхронный обратный вызов вместо блокировки / синхронного шага, как требуется для выполнения ShareFiltering ( )) - использовать синхронизированный объект с ожиданием () / уведомлением () для выполнения мониторинга перекрестного потока, поэтому эффект совпадает с сетевым запросом непосредственно в PerformingFiltering (), но это на самом деле происходит в нескольких потоках:
// 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();
}
}
Однако, я думаю, вы можете обнаружить, что самое простое решение - просто сделать свой сетевой запрос синхронно, непосредственно в методе PerformingFiltering (). Пример вышеуказанного кода - это только одна возможность, если у вас уже есть архитектура на месте для асинхронных вызовов ASInchrorsous / Callback API, и вы не хотите изменить это поведение, чтобы получить синхронные результаты в выполнении ShareFiltering ().
Другие советы
Я думаю, что ответ Джо - это путь. Однако я думаю, что вы должны использовать CountDownLatch. вместо ожидания / уведомления.
Причина в том, что с ожиданием / уведомлением вы рискуете о состоянии гонки, если ваша API на самом деле вернет Super Fast, прежде чем начать «ждать ()» ... в этом случае уведомлять не будет иметь эффект и ждать () будет ждать неопределенно Отказ С защелкой код будет выглядеть так (скопировано из Джо и модифицировано):
// 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;
CountDownLatch latch;
synchronized APIResult waitForAPI(CharSequence constraint) {
latch = new CountDownLatch(1);
someAPIObject.startAsyncNetworkRequest(constraint);
// At this point, control returns here, and the network request is in-progress in a different thread.
try {
// Will wait till the count is 0...
// If the count is already 0, it'll return immediately.
latch.await();
// 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.
// countDown() will wake up the other calling thread, allowing it to continue
// execution in the performFiltering() method, as usual.
latch.countDown();
}
}
Наконец, у меня недостаточно кредита, чтобы опубликовать комментарий, иначе я бы ...