Полный список
— размещаем на карте свои объекты
Мы можем размещать на карте маркеры со всплывающими подсказками, рисовать простейшие фигуры и накладывать свои текстуры. Напишем приложение и рассмотрим все это на примерах.
Подробную инструкцию о том, как создать и настроить проект, предназначенный для работы с гугл-картами, можно найти в Уроке 139.
Project name: P1401_GoogleMapsDraw
Build Target: Android 2.3.3
Application name: GoogleMapsDraw
Package name: ru.startandroid.develop.p1401googlemapsdraw
Create Activity: MainActivity
В strings.xml добавим строки:
Кнопка и фрагмент-карта
В onCreate мы находим наш фрагмент с картой и получаем от него объект GoogleMap методом getMap. Учитывайте, что этот метод может вернуть null.
Метод init пока пустой.
Метод onClickTest пока пустой.
Маркеры
Начнем с маркеров. Думаю, все в курсе, что это такое, если пользовались поиском в картах. Попробуем программно поставить маркер. Перепишем onClickTest:
Для добавления используем метод addMarker и на вход ему передаем объект MarkerOptions. Указываем координаты маркера (position) и текст (title), который будет отображен по нажатию на маркер.
Все сохраняем, запускаем приложение и жмем Test.
в точке (0, 0) появился маркер.
появился текст, который мы вводили.
Рассмотрим, какие возможности дает нам MarkerOptions.
alpha – прозрачность маркера, значение от 0 до 1
anchor – точка маркера, которая соответствует точке карты.
Рассмотрим маркер поближе
Сейчас на требуемое место на карте указывает его нижняя суженная часть. Если взять за единицу ширину и высоту маркера, то эту указательную точку маркера можно обозначить как (0.5, 1).
А т.к. мы можем в качестве маркера использовать свои иконки, вовсе необязательно, что у них указательная часть будет расположена также снизу по центру. Поэтому anchor дает возможность нам самим указать указательную точку маркера.
Например, указав (0.5, 0) мы получим маркер, который будет указывать своей верхней центральной частью.
draggable – маркер можно перетаскивать после установки
flat – настройка поведения маркера при повороте и наклоне карты. Если передать true, то маркер будет привязан к карте, т.е. будет вращаться и наклоняться вместе с картой. Если же false (по умолчанию) то маркер будет привязан к камере: при поворотах и наклонах карты он останется в том же положении.
icon – возможность кастомизации иконки маркера, на вход требует объект BitmapDescriptor, который в свою очередь может быть получен с помощью объекта BitmapDescriptorFactory.
Перепишем метод onClickTest:
В точку (-10, -10) мы ставим маркер по умолчанию, который можно получить методом defaultMarker, но при этом мы меняем его цвет на зеленый.
В точку (0, 0) мы ставим маркер по умолчанию, который можно получить методом defaultMarker. Цвет не меняем.
В точку (10, 10) поставим маркер в виде стандартной Android иконки, используя метод fromResource и указав требуемый drawable-ресурс.
Запускаем, жмем Test и наблюдаем маркеры:
BitmapDescriptorFactory также имеет другие методы для получения иконки маркера:
— fromBitmap, из Bitmap объекта
— fromFile, из файла внутреннего хранилища
— fromPath, из файла по указанному пути
Ну а для метода defaultMarker есть еще несколько готовых расцветок кроме зеленого, в хелпе они все указаны.
rotation – поворот маркера (в градусах) по часовой относительно точки anchor.
snippet – дополнительный текст для инфоокна (которое отображается по нажатию на маркер)
Метод addMarker при добавлении вернет вам объект Marker, для которого вы также позже сможете применять вышеописанные настройки с помощью методов set*.
Для отслеживания событий маркеров карта предоставляет нам пару слушателей.
OnMarkerClickListener (устанавливается методом setOnMarkerClickListener) имеет метод onMarkerClick, который дает нам Marker, на который было произведено нажатие.
OnMarkerDragListener (устанавливается методом setOnMarkerDragListener) имеет три метода для отслеживания перетаскивания маркера: onMarkerDragStart (перетаскивание начато), onMarkerDrag (перетаскивание в процессе) и onMarkerDragEnd (перетаскивание закончено).
Инфоокно
По нажатию на маркер появляется инфоокно с текстом. Показать это окно можно и программно, используя метод showInfoWindow объекта Marker.
Перепишем методы init и onClickTest:
Запустим приложение, появится маркер. Жмем Test и появляется инфоокно с текстами.
Метод hideInfoWindow скрывает инфоокно. Метод isInfoWindowShown подскажет, отображается ли для маркера инфоокно в данный момент.
Инфоокно можно кастомизировать. Перепишем метод init:
Мы добавляем два маркера и первый сохраняем в переменную marker. Далее вызываем метод setInfoWindowAdapter, в который создаем и передаем объект InfoWindowAdapter. Этот объект имеет два метода:
— getInfoWindow, замена всего инфоокна своим View (которое является результатом работы метода)
— getInfoContents, замена содержимого инфоокна своим View (которое является результатом работы метода)
Алгоритм такой. При вызове инфоокна система вызывает getInfoWindow и использует его View. Если getInfoWindow вернул null, то вызывается getInfoContents и используется его View. Если и здесь null, то создается стандартное инфоокно.
Мы в методе getInfoWindow по id проверяем, что это первый маркер, который мы создавали и для него создаем свое View (TextView с красным текстом Test getInfoWindow). Для всех других маркеров метод вернет null (а следовательно они пойдут в метод getInfoContents).
В методе getInfoContents мы создаем свое View (TextView с текстом Test getInfoContents) и используем его для всех маркеров.
Запускаем приложение, у нас появились два маркера. Жмем на первый:
Видим, что инфоокно полностью заменилось нашим View из getInfoWindow.
Жмем на второй маркер.
Здесь заменилось не все инфоокно, а только его содержимое. А рамка осталась.
Методом setOnInfoWindowClickListener мы можем повесить слушателя OnInfoWindowClickListener, который методом onInfoWindowClick оповестит нас о том, что произошло нажатие на инфоокно и даст нам Marker.
Фигуры
Карта дает нам возможность рисовать на ней простейшие фигуры: круги, линии, многоугольники.
Для этого есть три объекта:
— Polyline – набор точек, которые будут соединены линиями
— Polygon –набор точек, которые будут соединены линиями в т.ч. и от последней точки к первой
— Circle – круг, позволяет указать точку центра и радиус
Эти объекты допускают графические настройки такие как толщина и цвет линий, цвет заливки.
Давайте нарисуем три фигуры. Перепишем метод init:
Первая фигура – Polyline. Для настройки используется объект PolylineOptions. Указываем точки, цвет(color) и толщину(width) линий. Настройки цвета заливки здесь нет, т.к. фигура может быть незамкнутой. Добавляем фигуру к карте методом addPolyline.
Далее Polygon. Для настройки используется объект PolygonOptions. Указываем точки, цвет(strokeColor) и толщину линий(strokeWidth), и цвет заливки(fillColor). Добавляем методом addPolygon.
И Circle. Настраивается объектом CircleOptions. Указываем точку центра, радиус (в метрах), цвет(strokeColor) и толщину линий(strokeWidth), и цвет заливки(fillColor). Добавляем методом addCircle.
Запускаем приложение и видим результат.
Как видите вторая фигура замкнутая, хотя я и указывал всего 4 точки. Линия от последней к первой рисуется автоматически.
Фигуры также имеют настройки:
zIndex – который определяет, какая из двух фигур будет нарисована выше (поверх, ближе к нам) при их пересечении. Чем выше это значение, тем выше будет фигура.
geodesic (для Polyline и Polygon) – если true, то линии будут не прямыми, а соответствовать поверхности земли, т.е. немного закругленными. Это будет заметно на больших расстояниях.
Для PolygonOptions есть метод )» target=»_blank» rel=»noopener noreferrer»>addHole, он рисует Polygon внутри Polygon, образуя дыру
Результат будет таков
Методы добавления фигур к карте возвращают вам эти объекты, и вы можете в дальнейшем менять их настройки (set*) или удалить методом remove.
Overlay
Когда мы ставим маркер, он не меняет свой размер при зуме. А есть возможность наложить на карту изображение, которое будет так же, как и карта менять размер при приближении и отдалении.
Перепишем метод init:
Создаем и настраиваем объект GroundOverlayOptions, указывая нужное нам изображение (image) и его расположение (position), которое состоит из точки центра и размеров (ширина и высота) картинки в метрах.
Добавляем объект на карту методом addGroundOverlay.
Запускаем и видим результат.
Приблизим и повернем.
Видно, что картинка привязана к карте.
Расположение также можно указать методами:
position(LatLng location, float width) – аналогичен тому, что мы вызывали, но можно указать только ширину, а высота сама определится по размерам картинки
positionFromBounds (LatLngBounds bounds) – через объект LatLngBounds мы указываем юго-западную и северо-восточную точку на карте и картинка будет расположена в указанной области
Также этот объект поддерживает настройки:
zIndex – Z-уровень, кто кого выше при прорисовке
Метод добавления (addGroundOverlay) вернет вам объект GroundOverlay, который вы можете потом менять или удалять (remove).
На следующем уроке:
— получаем доступ к Canvas
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Работа с интерфейсом в Google Maps SDK для Android
Данная статья будет полезна тем, кто ранее не использовал в своей работе Google Maps SDK.
Под катом описаны основные приемы работы с картой, такие как добавление и управление маркерами, способы перемещения камеры над картой, управление зумом, построение маршрута и геокодинг. А так же ограничения и способы их обхода.
Источник
На написание статьи меня сподвиг собственный опыт, который я извлек при написании приложения для курьеров использующего в своей работе гугл карты. Так что все скриншоты и возможное упоминание бизнес логики будут происходить в контексте построения интерфейса курьера.
К сожалению Google Maps SDK for Android не позволяет изменять положение кнопок управления, т.н. UI controls, к ним относятся: IndoorLevelPicker — показ поэтажного плана строений, Compass — компас, My Location button — перейти на карте к текущему местоположению, Map toolbar — кнопи построения маршрута и открытия карты, а так же ZoomControls — увеличения и уменьшения маштаба карты.
На примере Map toolbar и ZoomControls посмотрим какие сложности могут возникнуть из-за невозможности сменить положение контролов и как это обойти.
Проблемы с отображением UI controls из SDK (выделено оранжевым) и их кастомные аналоги (выделено зеленым)
В данном случае у нас в правом нижнем углу расположена кнопка (floating action button) перехода к списку адресов заказов на доставку, на картинке слева видно, что ZoomControls оказались под ней и практически недоступны для нажатия. На картинке справа, при нажатии на маркер, появляются кнопки из Map toolbar, они так же оказались под кнопкой перехода к списку заказов.
Первое что нам необходимо сделать — это скрыть отображение оригинальных кнопок. Сделать это можно переопределив метод onMapReady, он вызывается в тот момент, когда карта готова к использованию.
Добавляем в верстку фрагмента нужные кнопки, там где они должны быть в соответствии с нашим дизайном:
Расположение кастомных кнопок управления картой
Затем в методе onCreateView указываем действия, которые должны произойти при нажатии на наши кнопки:
Особенность метода animateCamera в том, что маштаб изменяется плавно, а не мгновенно и если нужно, например, отключить анимацию конкретной кнопки зума, по достижению максимального или минимального маштаба, то для этого нужно переопределить метод onCameraIdle, который вызывается в момент прекращения изменения маштаба карты.
Что бы выполнить какое либо действие с маркером(кроме перетаскивания), например, создать новый заказ, удалить случайно поставленный маркер, перейти в уже существующий заказ или позвонить по телефону казанному в заказе добавляем в верстку соответствующие кнопки управления и прописываем их обработчики.
Кнопки управления маркером
Еще одна особенность, это то что в SDK нет кнопки для удаления поставленного на карту маркера. Для этого тоже делаем свою кнопку:
При нажатии на маркер открывается его заголовок, нажатие на который так же можно использовать для совершения какого либо действия, я при нажатии на заголовок нового маркера создаю новый заказ на доставку курьеру, а на маркер уже существующего заказа — открываю подробную информацию о доставке, включающюю перечень товаров.
Процесс вывода нескольких маркеров (считай списка заказов) на карту ничем принципиально не отличается от вывода одного маркера. Маркер состоит из координат (position), заголовка (title), мелкого текста под заголовком (snippet) и тэга (setTag) — его можно использовать для идентификации множества маркеров на карте.
Несколько маркеров на карте
Пара слов о геокодере
Геокодер используется для получения адреса, на основании координат. Поставив маркер на карте и нажав кнопку добавить заказ, мы получаем географические координаты нужной точки, т.е. широту и долготу. Но для удобства пользователя неплохо будет показать адрес в человекочитаемом виде, т.е., например, страна, город, улица, дом.
Google Maps SDK содержит класс Geocoder, вызвав его метод getFromLocation можно получить массив адресов по указанным координатам.
Для того, что бы не блокировать UI thread долгими, особенно если медленный или недоступный интернет, вызовами — будем использовать RxJava:
Полученный адрес точки на карте на основании географических координат
Источник