Утилита Google Maps: как получить все маркеры от ClusterManager <?>?

Извините за мой английский

Я попробовал метод ClusterManager<?>.getMarkerCollection().getMarkers() но возвращает пустую коллекцию.

Я использую в своем приложении Google Maps Utility Library . Каждый раз после поворота экрана я создаю AsynkTask и в фоновом потоке считывают данные из БД и добавляют элементы в ClusterManager :

 cursor.moveToFirst(); while (!cursor.isAfterLast()) { SomeData row = readSomeDataRow(cursor); clusterManager.addItem(new ClusterItemImpl(row)); cursor.moveToNext(); } 

Когда AsyncTask завершил свою работу (то есть в основном потоке), я попытался получить все маркеры из ClusterManager :

 clusterManager.cluster(); // cluster manager returns empty collection \|/ markers = clusterManager.getMarkerCollection().getMarkers(); 

Но ClusterManager возвращает пустую коллекцию.

Может быть, в тот момент, когда я вызываю getMarkers() ClusterManager пока не помещает маркеры на карту и сделает это немного позже (может быть в фоновом потоке). Если да, то как я могу уловить этот момент?

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

ПРЕДПОСЫЛКА: Давайте сначала рассмотрим реализацию ClusterManager.addItem из кода библиотеки:

 public void addItem(T myItem) { this.mAlgorithmLock.writeLock().lock(); try { this.mAlgorithm.addItem(myItem); } finally { this.mAlgorithmLock.writeLock().unlock(); } } 

Как вы можете видеть, при вызове clusterManager.addItem ClusterManager вызывает этот.mAlgorithm.addItem. MAlgorithm – это место, где хранится ваш элемент. Давайте посмотрим на конструктор по умолчанию ClusterManager:

 public ClusterManager(Context context, GoogleMap map, MarkerManager markerManager) { ... this.mAlgorithm = new PreCachingAlgorithmDecorator(new NonHierarchicalDistanceBasedAlgorithm()); ... } 

MAlgorithm создается как PreCachingAlgorithmDecorator, содержащий алгоритм NonHierarchicalDistanceBasedAlgorithm. К сожалению, поскольку mAlgorithm объявлен private, у нас нет доступа к элементам, которые добавляются в алгоритм. Тем не менее, есть счастливое решение! Мы просто инстанцируем mAlgorithm с помощью ClusterManager.setAlgorithm. Это позволяет нам получить доступ к классу алгоритмов.

Перейти к началу страницы | Отправить отзыв Временное решение: Вот ваш код с обходным путем.

  1. Поместите это объявление с переменными класса:

     private Algorithm<Post> clusterManagerAlgorithm; 
  2. В том месте, где вы создаете экземпляр своего ClusterManager, сразу же поставьте его:

      // Instantiate the cluster manager algorithm as is done in the ClusterManager clusterManagerAlgorithm = new NonHierarchicalDistanceBasedAlgorithm(); // Set this local algorithm in clusterManager clusterManager.setAlgorithm(clusterManagerAlgorithm); 
  3. Вы можете оставить свой код для вставки элементов в кластер точно так же.

  4. Когда вы хотите получить доступ к вставленным элементам, вы просто используете алгоритм в отличие от ClusterManager:

     Collection<ClusterItemImpl> items = clusterManagerAlgorithm.getItems(); 

Это возвращает элементы вместо объектов Marker, но я считаю, что это то, что вам нужно.

Переопределить один из них:

onBeforeClusterItemRendered

onBeforeClusterRendered

onClusterRendered

onClusterItemRendered

Как

  @Override protected void onClusterRendered(Cluster<MyItem> cluster, Marker marker) { super.onClusterRendered(cluster, marker); } 

Cluster.getItems () вернет маркеры в кластере

У меня была такая же проблема, чтобы получить все маркеры или, по крайней мере, получить количество маркеров. Думаю, я нашел решение получить маркеры.

Я пробовал, как ты

 markers = clusterManager.getMarkerCollection().getMarkers(); 

Попробуйте вместо этого

 markers = clusterManager.getClusterMarkerCollection().getMarkers(); 

Эта строка вернула мне маркеры, но я не уверен, что это результат, который мы хотим. Мне нужно проверить это.

ПРИМЕЧАНИЕ. Я бы написал свой ответ в качестве комментария, но мне не хватало смысла.

@ Это решение работает. Еще один взлом – использовать Reflection API для доступа к mAlgorithm (как упоминается Ethan mAlgorithm, где ваш элемент хранится) в поле класса ClusterManager .

 try { Field field = mClusterManager.getClass().getDeclaredField("mAlgorithm"); field.setAccessible(true); Object mAlgorithm = field.get(mClusterManager); List<MapItems> markers = new ArrayList<>(((Algorithm<MapItems>)mAlgorithm).getItems()); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } 

Примечание: – В будущем, если есть какие-либо изменения в имени поля (т. private Algorithm<T> mAlgorithm ), изменение должно быть выполнено в бизнес-логике.