Как я могу сделать два слушателя Google Maps? setOnCameraChangeListener

Как я могу создать двух слушателей? Один используется для кластеризации, а другой загружает новые элементы кластера на карту, если на карте нет элементов кластера.

       //needed for clustering
       map.setOnCameraChangeListener(mClusterManager);

       // need for loading clusteritems
       map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
       @Override
       public void onCameraChange(CameraPosition position) {

       // ifMarkesNotInsideMapReload...

Я думаю, что это невозможно, но кто-то может решить это...

Одна идея состоит в том, чтобы установить начальную позицию и опросить изменения вручную.. не круто:-)

Я использую кластерную библиотеку Google: Google cluster

4 ответа

Решение

Я смотрел в ClusterManager реализация библиотеки AMUtils и, похоже, она вызывает onCameraChange на вашей реализации ClusterRenderer если он также реализует OnCameraChangeListener, Просто заставьте его реализовать этот интерфейс.

Соответствующие части кода:

@Override
public void onCameraChange(CameraPosition cameraPosition) {
    if (mRenderer instanceof GoogleMap.OnCameraChangeListener) {
        ((GoogleMap.OnCameraChangeListener) mRenderer).onCameraChange(cameraPosition);
    }

Если вы используете DefaultClusterRendederсоздайте класс как:

public class MyClusterRenderer extends DefaultClusterRenderer implements OnCameraChangeListener {

Используйте Composite Pattern, чтобы создать класс, который является CameraChangeListener и содержит CameraChangeListeners, так что он может быть установлен в качестве единственного слушателя на карте при делегировании нескольким дочерним элементам, которые выполняют настоящую работу.

В этом случае вы бы создали CompositeCameraChangeListener класс, который реализует CameraChangeListener интерфейс и поддерживает список дочерних слушателей, которым он делегирует.

Какой-то псевдокод:

public class CompositeCameraChangeListener implements CameraChangeListener {
    private final List<CameraChangeListener> mListeners = new ArrayList<CameraChangeListener>();

    @Override
    public void onCameraChange(CameraPosition position) {
        for (CameraChangeListener listener in mListeners) {
            listener.onCameraChange(position);
        }
    }

    // Other methods to add, remove listeners
}

Тогда в вашем основном классе:

CompositeCameraChangeListener composite = new CompositeCameraChangeListener();
composite.add(mClusterManager);
composite.add(new CameraChangeListner() { ... });
map.setOnCameraChangeListener(composite);

Теперь, когда CompositeCameraChangeListenerВызывается метод, он перенаправляет вызов другим слушателям, и что касается вашего приложения, теперь у вас есть два (или более) слушателя, зарегистрированных для объекта, который предназначен для принятия только одного.

Для тех, кто борется с вышеупомянутым псевдокодом от TreKing, вы можете использовать фрагмент кода ниже

public class MultiListener implements GoogleMap.OnCameraChangeListener {
    private List<GoogleMap.OnCameraChangeListener> mListeners = new ArrayList<GoogleMap.OnCameraChangeListener>();

    public void registerListener (GoogleMap.OnCameraChangeListener listener) {
       mListeners.add(listener);
    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition)
    {
        for (GoogleMap.OnCameraChangeListener ccl: mListeners)
        {
            ccl.onCameraChange(cameraPosition);
        }
    }

}

и добавить в MultiListener

MultiListener ml = new MultiListener();
ml.registerListener(mClusterManager);
ml.registerListener(new GoogleMap.OnCameraChangeListener() {
               @Override
               public void onCameraChange(CameraPosition cameraPosition) {

                 // code here
               }
           }
    );
map.setOnCameraChangeListener(ml);

Включите менеджер кластеров onCameraChange в свой пользовательский слушатель смены камеры

mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        mClusterManager.onCameraChange(cameraPosition);
        .....
    }
});

Поскольку setOnCameraChangeListener устарел, лучше использовать setOnCameraIdleListener

map.setOnCameraIdleListener {
    //...
    clusterManager.onCameraIdle()
}
Другие вопросы по тегам