Случается такое что попадается проект в котором приходится изворачиваться с кастомизацией элементов на экране. Сейчас возможности доросли до такого уровня что почти каждый стандартный элемент в андроиде можно переписать под себя, раньше это тоже было возможно, но как-то никто не парился, а теперь настали новые времена, и заказчики под напором дизайнеров хотят все красивей и красивей разного рода вьюхи, бывает что некоторые просто нереално сделать с первого раза.
Но это статья не про такой вид вьюх. Сегодня все будет проще, так как нам нужно всего лишь сделать кастомный пин на карте, в котором будет находится фотка человека. Для этого мы создадим кастомную вьюху и в ней проделаем элементарные махинации по рисованию магии на экране.
У нас тут и Джордж Клуни, и Роберт Де Ниро и Дональд Трамп, прям отличная пьянка!
Начнем мы все с того же с чего я всегда начинаю статьи, — с настройки проекта, а это добавление библиотек в build.gradle. Использовать библиотеки всегда желательнее чем использовать самописные костыли, по этому старайтесь максимально чаще находить готовые библиотеки по каким-то задачам, будь то работа с сервером (Retofit), работа с базой данных (Realm или Room) или какая-то библиотека помогающая на пример с пермишенами в новых версиях андроида (Dexter).
app/build.gradle
И так, что же мы имеем у себя в app/build.gradle. У нас будет использоваться пара библиотек, а это — CircleImageView, ButterKnife, Google Map Services и RxAndroid. Последнюю я буду использовать чисто для красоты кода, не знаю как кому, а мне очень нравится как оно выглядит в проекте и всех настаиваю так же писать код. Так же у нас будет включена Java 8 для работы с лямбдой.
Теперь у нас готов плацдарм для работы с проектом. У нас создалась активити и леяут к ней, в ней мы будем создавать карту, подключается карта очень легко, в отличии от предыдущих версий когда требовалось кучу кода писать, теперь у нас достаточно создать на леяуте фрагмент с картой, и дальше подключить ее в активити, и все, у нас есть карта!
Как же будет выглядеть MainActivity с картой. Для начала нам нужно добавить фрагмент с картой в леяут, сделаем это.
activity_main.xml
Супер, у нас есть карта на экране активити, теперь нам нужно подключить и заставить ее работать в самом классе. Для этого нам нужно создать объект SupportMapFragment и подключить к нему наш фрагмент map.
MainActivity.java
Как видно из кода у нас есть объект GoogleMap который мы в дальнейшем будем использовать как метку для добавления пинов на карту, перемещение камеры по карте и так далее. И есть объект SupportMapFragment который собственно и есть карта, и к нему у нас подключен колбек getMapAsync который по готовности карты вернет нам что карта готова к работе, и дальше мы будем готовы устанавливать разные пины на карту и т.д. Так же для того что бы карта работала нам нужно добавить API Key для работы, его можно зарегистрировать тут. И после того как сгенерируете код для карты, нужно будет его указать в string.xml.
string.xml
Собственно дальше нам нужно создать класс который будет описывать создание пина из картинки и определенного шаблона. У нас будет три вида пинов, красный, желтый и зеленый, я это сделал чисто для примера, а так их можно сделать хоть 150 видов, но у нас их будет три. Для начала нам нужно создать вьюху которая будет шаблоном для пина. У нас так же будут использоваться три картинки для них и одна заглушка если нету картинки пользователя.
view_custom_map_pin.xml
В ней у нас RelativeLayout у которого наложен фон в виде одной из картинок для пина, так же внутри у нас ImageView скругленный для аватара, и TextView под ним для того что бы если у нас нет аватара то отображалось хотя бы имя, по умолчанию он не видимый.
Так же у нас используются цвета, белый, красный, зеленый и желтый, их я указал в colors.xml файле.
colors.xml
Ну а теперь напишем что бы это все работало так как нам нужно.
CustomPinView.java
Что мы тут видим? В методе init() инициализируем нашу вьюху, ButterKnife и дальше у нас идут методы сеттеры для имени и аватара. Что в имени то понятно, просто задаем имя, а вот в аватаре мы создаем на основе битмапа который нам передаст метод скачивающий фотку с интернета и присваиваем его в ImageView или же если битмап пустой то делаем картинку на основе статуса который у нас передается в mapStatus, и ставим в зависимости от статуса тот или иной цвет на фон и указываем имя пользователя.
Дальше нам нужно создать класс который будет скачивать фотку с интернета, для этого создадим класс который будет включать в себя все нужные методы для работы, в моем случае это будет один метод для скачивания фотографий.
Как я писал ранее в статье про RxAndroid мы создадим интерфейс который будет в себе содержать метод возвращающий нам в результате местоположение пина на карте и сам пин картинкой.
IRepository.java
Вот мы создали интерфейс, в котором создали метод возвращающий нам ResponseModel в котором у нас содержится Bitmap и LatLng. Вот его структура.
ResponseModel.java
В него мы передадим все параметры когда получим в итоге, и дальше из него же будем доставать эти данные для отображения на карте. А еще в метод getImages() мы передаем ссылку и PinsModel в котором у нас содержится вся информация по пину, айди, имя, картинка, и статус карты (цвет пина).
PinsModel.java
Дальше нам нужно создать реализацию интерфейса IRepository, и написать там метод для скачивания картинок с интернета.
RepositoryImpl.java
После того как мы заимплементировали IRepository в этот класс, нам предложит студия добавить обязательные методы, и после того как вы добавите их оно создаст наш метод из интерфейса в который мы написали реализацию скачивания и в дальнейшем преобразование в зависимости от статуса пин в наш кастомный. Метод createDrawableFromView() позволяет нам преобразовать наш пин в доступную для ImageView версию для отображения, по этому мы из пина делаем Bitmap. Да кстати хочу заметить что локейшн я сделал рандомный, так что пины будут распологаться рандомно на карте…
Ну а дальше осталось только вернуться в MainActivity и прописать создание пинов на карте. Для этого смотрим в метод onMapReady() который у нас на данный момент пустой, но буквально через секунду мы его заполним.
MainActivity.java
В самом начале метода мы присваиваем mMap его инстанс который вернул нам колбек, что бы дальше можно было работать с ним для добавления разных фишек на карту. Создаем список с нужными нам картинками и личностями, в моем случае их три, и потом в цикле я их отображаю скачивая их фотографии с помощью нашего класса RepositoryImpl. И в результате добавляю их на карту с кастомным локейшеном и кастомной картинкой.
Ну и осталось в манифесте прописать пермишен для работы с интернетом и мета данные для работы карты.
AndroidManifest.xml
Как то так. Дальше можно компилировать. Если нет ошибок это замечательно, если есть то проверяем еще раз и смотрим не забыли ли мы что-то добавить.
Исходники:
GitHub
Но это статья не про такой вид вьюх. Сегодня все будет проще, так как нам нужно всего лишь сделать кастомный пин на карте, в котором будет находится фотка человека. Для этого мы создадим кастомную вьюху и в ней проделаем элементарные махинации по рисованию магии на экране.
У нас тут и Джордж Клуни, и Роберт Де Ниро и Дональд Трамп, прям отличная пьянка!
Начнем мы все с того же с чего я всегда начинаю статьи, — с настройки проекта, а это добавление библиотек в build.gradle. Использовать библиотеки всегда желательнее чем использовать самописные костыли, по этому старайтесь максимально чаще находить готовые библиотеки по каким-то задачам, будь то работа с сервером (Retofit), работа с базой данных (Realm или Room) или какая-то библиотека помогающая на пример с пермишенами в новых версиях андроида (Dexter).
app/build.gradle
И так, что же мы имеем у себя в app/build.gradle. У нас будет использоваться пара библиотек, а это — CircleImageView, ButterKnife, Google Map Services и RxAndroid. Последнюю я буду использовать чисто для красоты кода, не знаю как кому, а мне очень нравится как оно выглядит в проекте и всех настаиваю так же писать код. Так же у нас будет включена Java 8 для работы с лямбдой.
Теперь у нас готов плацдарм для работы с проектом. У нас создалась активити и леяут к ней, в ней мы будем создавать карту, подключается карта очень легко, в отличии от предыдущих версий когда требовалось кучу кода писать, теперь у нас достаточно создать на леяуте фрагмент с картой, и дальше подключить ее в активити, и все, у нас есть карта!
Как же будет выглядеть MainActivity с картой. Для начала нам нужно добавить фрагмент с картой в леяут, сделаем это.
activity_main.xml
Супер, у нас есть карта на экране активити, теперь нам нужно подключить и заставить ее работать в самом классе. Для этого нам нужно создать объект SupportMapFragment и подключить к нему наш фрагмент map.
MainActivity.java
Как видно из кода у нас есть объект GoogleMap который мы в дальнейшем будем использовать как метку для добавления пинов на карту, перемещение камеры по карте и так далее. И есть объект SupportMapFragment который собственно и есть карта, и к нему у нас подключен колбек getMapAsync который по готовности карты вернет нам что карта готова к работе, и дальше мы будем готовы устанавливать разные пины на карту и т.д. Так же для того что бы карта работала нам нужно добавить API Key для работы, его можно зарегистрировать тут. И после того как сгенерируете код для карты, нужно будет его указать в string.xml.
string.xml
Собственно дальше нам нужно создать класс который будет описывать создание пина из картинки и определенного шаблона. У нас будет три вида пинов, красный, желтый и зеленый, я это сделал чисто для примера, а так их можно сделать хоть 150 видов, но у нас их будет три. Для начала нам нужно создать вьюху которая будет шаблоном для пина. У нас так же будут использоваться три картинки для них и одна заглушка если нету картинки пользователя.
view_custom_map_pin.xml
В ней у нас RelativeLayout у которого наложен фон в виде одной из картинок для пина, так же внутри у нас ImageView скругленный для аватара, и TextView под ним для того что бы если у нас нет аватара то отображалось хотя бы имя, по умолчанию он не видимый.
Так же у нас используются цвета, белый, красный, зеленый и желтый, их я указал в colors.xml файле.
colors.xml
Ну а теперь напишем что бы это все работало так как нам нужно.
CustomPinView.java
Что мы тут видим? В методе init() инициализируем нашу вьюху, ButterKnife и дальше у нас идут методы сеттеры для имени и аватара. Что в имени то понятно, просто задаем имя, а вот в аватаре мы создаем на основе битмапа который нам передаст метод скачивающий фотку с интернета и присваиваем его в ImageView или же если битмап пустой то делаем картинку на основе статуса который у нас передается в mapStatus, и ставим в зависимости от статуса тот или иной цвет на фон и указываем имя пользователя.
Дальше нам нужно создать класс который будет скачивать фотку с интернета, для этого создадим класс который будет включать в себя все нужные методы для работы, в моем случае это будет один метод для скачивания фотографий.
Как я писал ранее в статье про RxAndroid мы создадим интерфейс который будет в себе содержать метод возвращающий нам в результате местоположение пина на карте и сам пин картинкой.
IRepository.java
Вот мы создали интерфейс, в котором создали метод возвращающий нам ResponseModel в котором у нас содержится Bitmap и LatLng. Вот его структура.
ResponseModel.java
В него мы передадим все параметры когда получим в итоге, и дальше из него же будем доставать эти данные для отображения на карте. А еще в метод getImages() мы передаем ссылку и PinsModel в котором у нас содержится вся информация по пину, айди, имя, картинка, и статус карты (цвет пина).
PinsModel.java
Дальше нам нужно создать реализацию интерфейса IRepository, и написать там метод для скачивания картинок с интернета.
RepositoryImpl.java
После того как мы заимплементировали IRepository в этот класс, нам предложит студия добавить обязательные методы, и после того как вы добавите их оно создаст наш метод из интерфейса в который мы написали реализацию скачивания и в дальнейшем преобразование в зависимости от статуса пин в наш кастомный. Метод createDrawableFromView() позволяет нам преобразовать наш пин в доступную для ImageView версию для отображения, по этому мы из пина делаем Bitmap. Да кстати хочу заметить что локейшн я сделал рандомный, так что пины будут распологаться рандомно на карте…
Ну а дальше осталось только вернуться в MainActivity и прописать создание пинов на карте. Для этого смотрим в метод onMapReady() который у нас на данный момент пустой, но буквально через секунду мы его заполним.
MainActivity.java
В самом начале метода мы присваиваем mMap его инстанс который вернул нам колбек, что бы дальше можно было работать с ним для добавления разных фишек на карту. Создаем список с нужными нам картинками и личностями, в моем случае их три, и потом в цикле я их отображаю скачивая их фотографии с помощью нашего класса RepositoryImpl. И в результате добавляю их на карту с кастомным локейшеном и кастомной картинкой.
Ну и осталось в манифесте прописать пермишен для работы с интернетом и мета данные для работы карты.
AndroidManifest.xml
Как то так. Дальше можно компилировать. Если нет ошибок это замечательно, если есть то проверяем еще раз и смотрим не забыли ли мы что-то добавить.
Исходники:
GitHub
Комментариев нет:
Отправить комментарий