Отличие разных маркеров в Maps API v2 (уникальные идентификаторы)

У меня есть ArrayList пользовательского класса. В списке около 10 объектов, каждый с подробностями, такими как Title, Snippet, LatLng. Я успешно добавил все 10 на карту, используя свои собственные функции класса, такие как getTitle, getSnippet, getLatLng и т. д.

Теперь, когда я щелкаю информационное окно (маркера), я хочу иметь возможность каким-то образом ЗНАТЬ, какому объекту моего пользовательского класса соответствует этот маркер.

Например, если я нажму на рынок McDonald's, я хочу знать, какому элементу из моего ArrayList принадлежит этот маркер.

Я просматривал MarkerOptions и, похоже, там нет ничего, что я мог бы использовать для идентификации соответствующего пользовательского объекта.

Если вопрос слишком запутанный, позвольте мне упростить его:

ArrayList<CustomObj> objects = blah
map.addMarker(new MarkerOptions().position(new LatLng(
                            Double.parseDouble(result.get(i).getCompanyLatLng()
                                    .split(",")[0]), Double.parseDouble(result
                                    .get(i).getCompanyLatLng().split(",")[1])))
                                    .title(result.get(i).getCompanyName())
                                    .snippet(result.get(i).getCompanyType())
                                    .icon(BitmapDescriptorFactory
                                            .fromResource(R.drawable.pin)));

Теперь, когда это нажато, я перехожу на следующую страницу. Следующая страница должна знать, КАКОЙ объект был нажат, чтобы я мог отправить другие данные на эту страницу (например, URL-адреса изображений, которые необходимо загрузить и т. д.).

Как мне добавить уникальное целое число или любой идентификатор к моему маркеру?


person Asim    schedule 23.05.2013    source источник
comment
mMap.setOnMarkerClickListener(new OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker arg0) { if(arg0.getTitle().equals(marker 1 title)) Toast.makeText(MainActivity.this, arg0.getTitle(),1000) .show();вернуть true;} }); вы можете использовать прослушиватель маркеров, чтобы проверить и использовать заголовок для сравнения, чтобы узнать, какой маркер был нажат   -  person Raghunandan    schedule 23.05.2013
comment
:) Заголовки в моем случае не всегда уникальны и, следовательно, не могут использоваться для этой цели.   -  person Asim    schedule 23.05.2013
comment
вы можете использовать getId() в этом случае.   -  person Raghunandan    schedule 23.05.2013


Ответы (5)


Один правильный способ - использовать Map<Marker, CustomObj>, в котором хранятся все маркеры:

Marker marker = map.addMarker(...);
map.put(marker, result.get(i));

и в onInfoWindowClick:

CustomObj obj = map.get(marker);

Еще одна попытка — использовать расширения Android Maps, которые добавляют методы getData и setData к Marker. , поэтому вы можете назначить свой объект CustomObj после создания маркера и получить его в любом обратном вызове.

person MaciejGórski    schedule 23.05.2013
comment
Я закончил тем, что использовал расширения карт. Я бы хотел, чтобы Google это исправил. - person Asim; 23.07.2013
comment
@Asim Я не думаю, что это требует исправления. Если бы такие функции (getData и setData) находились внутри исходной библиотеки, все ваши объекты должны были бы быть Parcelable и их отправка через IPC в сервисы Google Play заняла бы дополнительное время. Использование Map является хорошим обходным путем, расширения Android Maps просто делают этот обходной путь более удобным. - person MaciejGórski; 23.07.2013

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

Чтобы найти нужный объект, я просто перебираю их:

for(SomeObject anObject : someObjects) {
    if(marker.getSnippet().equalsIgnoreCase(anObject.getID())) {
        //you got at match
    }
}
person Warpzit    schedule 23.05.2013
comment
Но у меня есть информация в сниппетах.. Полезная информация, которую нужно отобразить - person Asim; 23.05.2013
comment
@ Асим, ты тоже можешь получить эту информацию от объекта, верно? Тогда бери оттуда. Информация нужна только тогда, когда вы ее показываете. - person Warpzit; 23.05.2013

Согласно обсуждению по следующей ссылке, Marker.equals и Marker.hashCode иногда не работают. Например, когда карта панорамируется или масштабируется, или перезапускается/возобновляется.

Добавить тег/идентификатор к маркерам

Таким образом, идентификатор маркера является лучшим ключом, чем сам маркер для HashMap.

Map<String, MyObject> markerMap = new HashMap<String, MyObject>();
Marker marker = map.addMarker(...);
MyObject myObject = new MyObject();
markerMap.put(marker.getId(), myObject);
person Alpha Huang    schedule 01.08.2014

Я думаю, используя широту и долготу, это можно было бы сделать

map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {

        @Override
        public boolean onMarkerClick(final Marker marker) {
            LatLng pos = marker.getPosition();
            int arryListPosition = getArrayListPosition(pos);
            return true;
        }
    });

и метод getArrayListPosition есть

private int getArrayListPosition(LatLng pos) {
    for (int i = 0; i < result.size(); i++) {
        if (pos.latitude == result.get(i).getCompanyLatLng().split(",")[0]) {
            if (pos.longitude == result.get(i).getCompanyLatLng()
                    .split(",")[1])
                return i;
        }
    }
    return 0;
}

Этот метод вернет вам позицию вашего ArrayList кого Marker вы нажали. и вы можете получить данные из этой позиции.

Надеюсь, поможет...

person AnujMathur_07    schedule 23.05.2013
comment
Это хорошая идея. Я попробую и отмечу ваш ответ как правильный, если он работает хорошо. - person Asim; 23.05.2013
comment
Но если у вас есть 2 маркера в одном и том же месте, вы облажались. Это, безусловно, не лучший вариант по сравнению с использованием title или snippet. - person Warpzit; 23.05.2013
comment
@Warpzit: да, ты прав. Но если вы добавляете 2 или более маркеров на один и тот же LatLng, то какой в ​​этом смысл. Маркеры используются для отображения какой-либо точки на карте. Таким образом, одна и та же широта будет указывать на одну и ту же позицию, и я думаю, что данные для этой точки будут одинаковыми для всех маркеров. - person AnujMathur_07; 24.05.2013

Я опоздал с ответом на 4 года, но я действительно поражен, почему никто не упомянул marker.setTag и marker.getTag.

Как написано в документах Google API,

Это проще, чем хранить отдельный Map<Marker, Object>

Они ввели setTag и getTag, чтобы избежать использования Map<...>. Вы можете использовать его следующим образом.

Marker marker = map.addMarker(...);
marker.setTag(result.get(i));  //Store your marker information here.

//To fetch your object...
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
    @Override
    public boolean onMarkerClick(Marker marker) {
        CustomObj obj = (CustomObj)marker.getTag();
        //Your click handle event
        // Pass the obj to another activity and you are done
        return false;
    }
});
person Shaishav Jogani    schedule 09.06.2017