Отображение пользовательского InfoWindow для Android Библиотеки утилит Maps для Android

Я использую библиотеку Утилита Google Maps для Android, которая позволяет создавать кластеры он отображает, и мне нужно показать пользовательский InfoWindow, но я не могу найти никакого способа сделать это. Чтобы показать информационное окно, у меня есть следующий класс, и в методе onClusterItemRendered у меня есть доступ к информации о маркере:

class MyClusterRenderer extends DefaultClusterRenderer<MarkerItem> {

    public MyClusterRenderer(Context context, GoogleMap map,
            ClusterManager<MarkerItem> clusterManager) {
        super(context, map, clusterManager);
    }

    @Override
    protected void onBeforeClusterItemRendered(MarkerItem item,
            MarkerOptions markerOptions) {
        super.onBeforeClusterItemRendered(item, markerOptions);
        markerOptions.title(String.valueOf(item.getMarkerId()));
    }

    @Override
    protected void onClusterItemRendered(MarkerItem clusterItem,
            Marker marker) {
        super.onClusterItemRendered(clusterItem, marker);
    }
}

Есть ли кто-нибудь, кто пользовался библиотекой и знает, как показать пользовательское InfoWindow так, как оно использовалось в Картах Google? Нравиться:

getMap().setInfoWindowAdapter(new InfoWindowAdapter() {

    @Override
    public View getInfoWindow(Marker arg0) {
        return null;
    }

    @Override
    public View getInfoContents(Marker arg0) {
        return null;
    }
});

person noloman    schedule 19.02.2014    source источник


Ответы (2)


Да, это можно сделать. ClusterManager поддерживает два MarkerManager.Collections:

  • один для кластерных маркеров и
  • один для отдельных маркеров предметов

Вы можете установить собственный InfoWindowAdapter для каждого из этих типов маркеров независимо.


Реализация

Сначала установите MarkerManager вашего ClusterManager в качестве InfoWindowAdapter карты:

ClusterManager<MarkerItem> clusterMgr = new ClusterManager<MarkerItem>(context, map);
map.setInfoWindowAdapter(clusterMgr.getMarkerManager());

Затем установите свой собственный InfoWindowAdapter в качестве адаптера для одной или обеих коллекций маркеров:

clusterMgr.getClusterMarkerCollection().setOnInfoWindowAdapter(new MyCustomAdapterForClusters());
clusterMgr.getMarkerCollection().setOnInfoWindowAdapter(new MyCustomAdapterForItems());

Последняя часть — это сопоставление необработанного объекта Marker, который вы получите в обратном вызове вашего пользовательского InfoWindowAdapter, с объектами ClusterItem, которые вы добавили на карту в первую очередь. Этого можно добиться с помощью слушателей onClusterClick и onClusterItemClick следующим образом:

map.setOnMarkerClickListener(clusterMgr);
clusterMgr.setOnClusterClickListener(new OnClusterClickListener<MarkerItem>() {
    @Override
    public boolean onClusterClick(Cluster<MarkerItem> cluster) {
        clickedCluster = cluster; // remember for use later in the Adapter
        return false;
    }
});
clusterMgr.setOnClusterItemClickListener(new OnClusterItemClickListener<MarkerItem>() {
    @Override
    public boolean onClusterItemClick(MarkerItem item) {
        clickedClusterItem = item;
        return false;
    }
});

Теперь у вас есть все необходимое для сборки пользовательского содержимого InfoWindow в соответствующих адаптерах! Например:

class MyCustomAdapterForClusters implements InfoWindowAdapter {
    @Override
    public View getInfoContents(Marker marker) {
        if (clickedCluster != null) {
            for (MarkerItem item : clickedCluster.getItems()) {
                // Extract data from each item in the cluster as needed
            }
        }
        // build your custom view
        // ...
        return view;
    }
}
person RonR    schedule 23.02.2014
comment
Молодец! Я просто хочу предупредить людей, я не заметил фрагмент кода: map.setOnMarkerClickListener(clusterMgr); и обратный вызов никогда не срабатывал. Очевидно, нужно сделать так, как прокомментировано в исходном коде: /*Sets a callback that's invoked when an individual ClusterItem is tapped. Note: For thislistener to function, the ClusterManager must be added as a click listener to the map. */ public void setOnClusterItemClickListener(OnClusterItemClickListener<T> listener) { mOnClusterItemClickListener = listener; mRenderer.setOnClusterItemClickListener(listener); } - person Dmitry Gryazin; 07.07.2014
comment
Я не совсем уверен, что вы имеете в виду? Я вызываю map.setOnMarkerClickListener(clusterMgr) в приведенном выше примере кода непосредственно перед установкой прослушивателей кликов onCluster и onClusterItem. - person RonR; 08.07.2014
comment
Все в порядке, это была просто моя ошибка, поэтому я хотел подчеркнуть этот момент. - person Dmitry Gryazin; 08.07.2014
comment
Боролся с подобной проблемой, пока не наткнулся на ваш комментарий. Это открыло мне глаза :) Спасибо - person Drew; 24.09.2014
comment
Похоже, что теперь, начиная с 0.3.2, есть гораздо лучший способ сделать это, github.com/googlemaps/android-maps-utils/issues/48 - person rfay; 22.10.2014
comment
setOnInfoWindowAdapter, показывающий неразрешенную ссылку - person ABDUL RAHMAN; 02.12.2020

Итак, в основном ваш класс начинается так:

private class MarkerItemClusterRenderer extends
        DefaultClusterRenderer<MarkerItem> {
    public MarkerItemClusterRenderer(Context context, GoogleMap map,
            ClusterManager<MarkerItem> clusterManager) {
    ...

Итак, в этом параметре map типа GoogleMap вы должны указать свой setInfoWindowAdapter.

person noloman    schedule 19.02.2014
comment
это разработка первого ответа или? - person Njeru Cyrus; 20.10.2018