Я пытаюсь сделать заказ InfoWindow
после нажатия на маркер с новым Google Maps API v2. Я хочу, чтобы это выглядело в оригинальном приложении карт от Google. Как это:
Когда у меня ImageButton
внутри, это не работает - все InfoWindow
спит и не только ImageButton
. Я читал, что это потому, что нет View
самого себя, но это снимок, поэтому отдельные элементы нельзя отличить друг от друга.
РЕДАКТИРОВАТЬ: В документации (спасибо Disco S2 ):
Как упоминалось в предыдущем разделе о информационных окнах, информационное окно не является живым видом, скорее, оно отображается на карте в виде изображения. В результате все прослушиватели, которые вы устанавливаете в представлении, игнорируются, и вы не можете различить события щелчка в различных частях представления. Рекомендуется не размещать интерактивные компоненты, такие как кнопки, флажки или текстовые вводы, в своем пользовательском информационном окне.
Но если Google использует это, должен быть какой-то способ сделать это. У кого-нибудь есть идеи?
источник
View.draw(Canvas)
) ... Это означает, что любые последующие изменения представления не будут отражены в информационном окне на карте. Чтобы обновить информационное окно позже Кроме того, информационное окно не будет учитывать какую-либо интерактивность, типичную для обычного вида, такую как события касания или жеста. Однако вы можете прослушать общее событие щелчка во всем информационном окне, как описано в разделе ниже. ... в твоем примере только textviewОтветы:
Я сам безуспешно искал решение этой проблемы, поэтому мне пришлось свернуть свой собственный, которым я хотел бы поделиться здесь с вами. (Прошу прощения за мой плохой английский) (Немного безумно отвечать на другого чешского парня по-английски :-))
Первым делом я попытался использовать старый добрый
PopupWindow
. Это довольно просто - нужно только послушать,OnMarkerClickListener
а затем показать обычайPopupWindow
над маркером. Некоторые другие ребята из StackOverflow предложили это решение, и оно на первый взгляд выглядит довольно неплохо. Но проблема с этим решением обнаруживается, когда вы начинаете перемещать карту. Вы должны переместить что-PopupWindow
то самостоятельно, что возможно (слушая некоторые события onTouch), но ИМХО, вы не можете заставить его выглядеть достаточно хорошо, особенно на некоторых медленных устройствах. Если вы делаете это простым способом, он «прыгает» с одного места на другое. Вы также можете использовать некоторые анимации, чтобы отшлифовать эти прыжки, но таким образомPopupWindow
всегда будет «шаг позади», где он должен быть на карте, что мне просто не нравится.В этот момент я думал о каком-то другом решении. Я понял, что на самом деле мне не нужно так много свободы - показывать свои собственные представления со всеми возможными возможностями (такими как анимированные индикаторы выполнения и т. Д.). Я думаю, что есть веская причина, почему даже инженеры Google не делают этого таким образом в приложении Google Maps. Все, что мне нужно, это кнопка или две в InfoWindow, которые будут показывать нажатое состояние и запускать некоторые действия при нажатии. Поэтому я пришел к другому решению, которое разделено на две части:
Первая часть:
первая часть должна быть в состоянии поймать щелчки на кнопках, чтобы вызвать какое-то действие. Моя идея заключается в следующем:
MapFragment
(илиMapView
) внутри пользовательской ViewGroup (моя называется MapWrapperLayout)MapWrapperLayout
dispatchTouchEvent и (если InfoWindow в данный момент отображается) сначала направьте MotionEvents к ранее созданному InfoWindow. Если он не использует MotionEvents (например, из-за того, что вы не щелкаете по какой-либо кликабельной области внутри InfoWindow и т. Д.), То (и только тогда) опускайте события до суперкласса MapWrapperLayout, чтобы он в конечном итоге был доставлен на карту.Вот исходный код MapWrapperLayout:
Все это сделает представления внутри InfoView снова «живыми» - OnClickListeners начнет срабатывать и т. Д.
Вторая часть: остающаяся проблема заключается в том, что вы, очевидно, не видите никаких изменений пользовательского интерфейса вашего InfoWindow на экране. Для этого вам нужно вручную вызвать Marker.showInfoWindow. Теперь, если вы выполните какое-либо постоянное изменение в вашем InfoWindow (например, измените метку кнопки на что-то другое), этого достаточно.
Но показать нажатие кнопки или что-то в этом роде сложнее. Первая проблема в том, что (по крайней мере) я не смог заставить InfoWindow показывать нормальное нажатие кнопки. Даже если я долго нажимал кнопку, она просто оставалась не нажатой на экране. Я считаю, что это то, что обрабатывается самой платформой карты, которая, вероятно, следит за тем, чтобы не показывать какое-либо переходное состояние в информационных окнах. Но я могу ошибаться, я не пытался это выяснить.
То, что я сделал, это еще один неприятный хак - я прикрепил
OnTouchListener
кнопку к кнопке и вручную переключил ее фон, когда кнопка была нажата или отпущена, для двух пользовательских элементов рисования - один с кнопкой в нормальном состоянии, а другой в нажатом состоянии. Это не очень приятно, но работает :). Теперь я мог видеть, как кнопка переключается между нормальным и нажатием на экране.Есть еще один последний глюк - если вы нажимаете кнопку слишком быстро, она не показывает нажатое состояние - она просто остается в своем нормальном состоянии (хотя сам щелчок срабатывает, поэтому кнопка «работает»). По крайней мере, именно так это проявляется на моем Galaxy Nexus. Поэтому последнее, что я сделал, это то, что я немного задержал кнопку в нажатом состоянии. Это также довольно уродливо, и я не уверен, как это будет работать на некоторых старых, медленных устройствах, но я подозреваю, что даже сама структура карты делает что-то подобное. Вы можете попробовать это сами - когда вы щелкаете все окно InfoWindow, оно остается в нажатом состоянии дольше, чем обычные кнопки (опять же - по крайней мере, на моем телефоне). И это на самом деле, как это работает даже в оригинальном приложении Google Maps.
Во всяком случае, я написал собственный класс, который обрабатывает изменения состояния кнопок и все другие вещи, которые я упомянул, так что вот код:
Вот пользовательский файл макета InfoWindow, который я использовал:
Файл макета тестовой активности (
MapFragment
находящийся внутриMapWrapperLayout
):И, наконец, исходный код тестовой деятельности, который склеивает все это вместе:
Вот и все. До сих пор я проверял это только на своих Galaxy Nexus (4.2.1) и Nexus 7 (также 4.2.1), я попробую это на каком-нибудь Gingerbread телефоне, когда у меня будет такая возможность. До сих пор я обнаружил ограничение, заключающееся в том, что вы не можете перетаскивать карту из-под своей кнопки на экране и перемещать карту. Возможно, это можно как-то преодолеть, но сейчас я могу жить с этим.
Я знаю, что это уродливый хак, но я просто не нашел ничего лучше, и мне так нужен этот шаблон проектирования, что это действительно повод вернуться к платформе map v1 (чего, кстати, я бы очень хотел избежать для нового приложения с фрагментами и т. д.). Я просто не понимаю, почему Google не предлагает разработчикам какой-либо официальный способ иметь кнопку в InfoWindows. Это такой общий шаблон дизайна, более того, этот шаблон используется даже в официальном приложении Google Maps :). Я понимаю причины, по которым они не могут просто заставить ваши представления «жить» в InfoWindows - это, вероятно, снизит производительность при перемещении и прокрутке карты. Но должен быть какой-то способ достичь этого эффекта без использования представлений.
источник
view.setBackground(bgDrawablePressed);
наif (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { view.setBackgroundDrawable(bgDrawablePressed); }else{ view.setBackground(bgDrawablePressed); }
для работы в Android Gingerbread, обратите внимание: есть еще одно вхождениеview.setBackground
в коде.Я вижу, что этот вопрос уже старый, но все же ...
Мы создали библиотеку sipmle в нашей компании для достижения желаемого - интерактивного информационного окна с представлениями и всем остальным. Вы можете проверить это на github .
Я надеюсь, что это помогает :)
источник
Вот мой взгляд на проблему. Я создаю
AbsoluteLayout
оверлей, который содержит информационное окно (обычный вид с каждым кусочком интерактивности и возможностями рисования). Затем я запускаю программу,Handler
которая синхронизирует положение информационного окна с положением точки на карте каждые 16 мс. Звучит безумно, но на самом деле работает.Демонстрационное видео: https://www.youtube.com/watch?v=bT9RpH4p9mU (учтите, что производительность снижается из-за одновременной работы эмулятора и записи видео).
Код демо: https://github.com/deville/info-window-demo
Статья с подробностями (на русском языке): http://habrahabr.ru/post/213415/
источник
Для тех, кто не смог получить
choose007's
ответ и запуститьЕсли
clickListener
вchose007's
решении все время не работает должным образом , попробуйте реализоватьView.onTouchListener
вместоclickListener
. Обработайте событие касания, используя любое действиеACTION_UP
илиACTION_DOWN
. По некоторым причинам, картыinfoWindow
вызывают странное поведение при отправкеclickListeners
.Редактировать: это, как я сделал это шаг за шагом
Сначала надуйте свое собственное информационное окно (глобальную переменную) где-нибудь в вашей деятельности / фрагменте. Моя в пределах фрагмента. Также убедитесь, что корневое представление в макете вашего информационного окна является линейным (по какой-то причине относительное расположение занимало всю ширину экрана в информационном окне)
Затем выполните обратный вызов onMapReady для Google Maps Android Android (следуйте этому, если вы не знаете, что такое OnMapReady Карты> Документация - Начало работы )
MapWrapperLayout
инициализация http://stackoverflow.com/questions/14123243/google-maps-android-api-v2- interactive-infowindow-like-in-original-android-go / 15040761 # 15040761 39 - высота маркера по умолчанию 20 - смещение между нижний край InfoWindow по умолчанию и нижний край его содержимого * /Метод SetInfoWindow
Ручка маркера нажимается отдельно
источник
Просто предположение, у меня недостаточно опыта, чтобы попробовать это ...) -:
Поскольку GoogleMap является фрагментом, должна быть возможность поймать событие маркера onClick и показать пользовательский вид фрагмента . Фрагмент карты все еще будет виден на заднем плане. Кто-нибудь пробовал это? Любая причина, почему это не могло работать?
Недостатком является то, что фрагмент карты будет зависать на фоне, пока пользовательский фрагмент информации не вернет ему контроль.
источник
Для этого вопроса я создал пример проекта студии android.
вывод снимков экрана: -
Скачать полный исходный код проекта Нажмите здесь
Обратите внимание: вы должны добавить свой ключ API в Androidmanifest.xml
источник
Это действительно просто.
Просто добавьте приведенный выше код в ваш класс, где вы используете GoogleMap. R.layout.info_window_layout - это наш пользовательский макет, который показывает вид, который появится вместо информационного окна. Я только добавил текстовое представление здесь. Вы можете добавить дополнительный вид здесь, чтобы сделать его как образец оснастки. Мой info_window_layout был
Надеюсь, это поможет. Рабочий пример пользовательского информационного окна можно найти по адресу http://wptrafficanalyzer.in/blog/customizing-infowindow-contents-in-google-map-android-api-v2-using-infowindowadapter/#comment-39731.
РЕДАКТИРОВАНИЕ: Этот код показывает, как мы можем добавить пользовательский вид в infoWindow. Этот код не обрабатывал нажатия на элементы пользовательского просмотра. Поэтому он близок к ответу, но не совсем к ответу, поэтому не принимается как ответ.
источник