5

Я использую Google Maps и его утилиту кластеризации в своем приложении. Сама кластеризация работает нормально, но у меня проблема, когда я пытаюсь справиться с изменениями конфигурации.Android, обратный вызов при завершении кластеризации карт

Это мой случай:

  1. Пользователь видит карту на экране, который является fragment.
  2. Когда кластеризация завершена, появляются маркеры на карте. Пользователь может взаимодействовать с markers.
  3. Когда пользователь выбирает , он подсвечивается и отображается BottomSheet.

Если пользователь поворачивает экран (то есть изменение конфигурации происходит), я сохраняю то, что маркер было выбрано с помощью onSaveInstanceState (на самом деле я не экономлю сам маркер, а только ссылку на соответствующую List запись типа ID). Затем я хочу восстановить этот пользовательский выбор, который был до изменения конфигурации.

Кластеризация сама выполняется так:

clusterManager.clearItems(); 
clusterManager.addItems(eventManager.getEventList()); 
clusterManager.cluster(); 

Этот код выполняется, когда данные, полученные от сервера. Очевидно, что при кластеризации все markers также воссоздаются. Поэтому, чтобы выделить предыдущий выбор пользователя (предыдущий), я должен знать, КОГДА программа кластеризации завершает свою работу. К тому времени я уверен, что я могу спокойно использовать такие функции, как:

clusterManager.getRenderer()).getMarker(<param>) 

и

clusterManager.getRenderer()).getClusterItem(<param>) 

в противном случае, они будут возвращаться null иногда, если кластеризация задача еще не завершена.

Однако, когда кластеризация завершена, я не могу найти разумный способ, как получить ответ от утилиты кластеризации (т. Е. ClusterManager). Я думаю, что нужно обновить этот стандартный код кластерного:

/** 
    * Runs the clustering algorithm in a background thread, then re-paints when results come back. 
    */ 
    private class ClusterTask extends AsyncTask<Float, Void, Set<? extends Cluster<T>>> { 
     @Override 
     protected Set<? extends Cluster<T>> doInBackground(Float... zoom) { 
      mAlgorithmLock.readLock().lock(); 
      try { 
       return mAlgorithm.getClusters(zoom[0]); 
      } finally { 
       mAlgorithmLock.readLock().unlock(); 
      } 
     } 

     @Override 
     protected void onPostExecute(Set<? extends Cluster<T>> clusters) { 
      mRenderer.onClustersChanged(clusters); 
     } 
    } 

Я думаю, что onPostExecute должен дать ответ не только Renderer, но пользователю ClusterManager (как мой fragment), что кластеризация делается. Но я не хочу изменять стандартный код.

Есть ли лучший способ справиться с этим случаем?

+1

Вы пробовали использовать 'OnMapLoadedCallback'? Согласно документации (https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnMapLoadedCallback) 'onMapLoaded()' вызывается, когда карта закончила рендеринг – antonio

+0

Ну, это может быть хорошо, но проблема в том, что я могу рисовать маркеры и кластеры сразу после получения данных с сервера, но иногда карта загружается до получения данных (из-за проблем с подключением и т. д.). Так что, наверное, это не сработает. – rofl

ответ

0

Вы идете об этом неправильно.

Вы должны осуществлять:

class YourClusterItemRenderer extends DefaultClusterRenderer<YourClusterItem> 

и установить его в ClusterManager в качестве средства отображения, как это:

mClusterManager.setRenderer(new YourClusterItemRenderer(...)); 

переопределять методы YourClusterItemRenderer в onBeforeClusterItemRendered и onBeforeClusterRendered и там вы можете изменить то, что каждый маркер выглядит в соответствии с ваша логика по параметрам с вашего сервера.

Итак, когда ClusterManager заканчивает рендеринга все ваши маркеры уже смотреть, как вы хотите их в соответствии с состоянием пользователя и т.д.