AutoCompleTeTextView не отображать результат даже при обновлении arrayAdapter

StackOverflow https://stackoverflow.com/questions/2671404

Вопрос

Я пытаюсь получить 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();
  }
}

Наконец, у меня недостаточно кредита, чтобы опубликовать комментарий, иначе я бы ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top