С помощью Maps SDK для Android можно отслеживать события на карте.
Примеры кода
Репозиторий ApiDemos на сайте GitHub содержит пример, который демонстрирует работу событий и прослушивателей:
Java
- EventsDemoActivity: события кликов на карте и изменений положения камеры.
- CameraDemoActivity: события изменений положения камеры.
- CircleDemoActivity: события кликов и перетаскиваний маркера.
- GroundOverlayDemoActivity: события кликов по наземным наложениям.
- IndoorDemoActivity: события на схемах зданий.
- MarkerDemoActivity: события для маркеров и информационных окон.
- PolygonDemoActivity: события для многоугольников.
Kotlin
- EventsDemoActivity: события кликов на карте и изменений положения камеры.
- CameraDemoActivity: события изменений положения камеры.
- CircleDemoActivity: события кликов и перетаскиваний маркера.
- GroundOverlayDemoActivity: события кликов по наземным наложениям.
- IndoorDemoActivity: события на схемах зданий.
- MarkerDemoActivity: события для маркеров и информационных окон.
- PolygonDemoActivity: события для многоугольников.
События клика и длительного клика
Чтобы приложение реагировало на нажатие в определенной точке карты, используйте прослушиватель OnMapClickListener
, который устанавливается с помощью метода GoogleMap.setOnMapClickListener(OnMapClickListener)
. Когда пользователь нажимает на карту, инициируется событие onMapClick(LatLng)
, сообщающее координаты точки, в которой произошел клик. Если вам требуются координаты соответствующей точки на экране в пикселях, вы можете запросить объект Projection
. Он позволяет переводить широту и долготу в экранные координаты в пикселях.
Кроме того, вы можете отслеживать длительные нажатия с помощью интерфейса OnMapLongClickListener
. Чтобы добавить его на карту, вызовите GoogleMap.setOnMapLongClickListener(OnMapLongClickListener)
.
Этот прослушиватель работает так же, как прослушиватель обычных кликов. При обнаружении долгого нажатия инициируется метод обратного вызова onMapLongClick(LatLng)
.
Отключение событий кликов в упрощенном режиме
Чтобы отключить события кликов на карте в упрощенном режиме, вызовите метод setClickable()
в представлении, которое содержит MapView
или MapFragment
. Это применяется, например, при отображении одной или нескольких карт в представлении в виде списка, когда вам необходимо, чтобы клик вызывал действие, не имеющее отношения к карте.
Отключать события кликов можно только в упрощенном режиме. Отключение этих событий также отключает реакцию маркеров на клики. Это не влияет на другие элементы управления картой.
Для MapView
:
Java
MapView mapView = findViewById(R.id.mapView); mapView.setClickable(false);
Kotlin
val mapView = findViewById<MapView>(R.id.mapView) mapView.isClickable = false
Для MapFragment
:
Java
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); View view = mapFragment.getView(); view.setClickable(false);
Kotlin
val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment val view = mapFragment.view view?.isClickable = false
События, связанные с изменением положения и настроек камеры
Модель представления карты предполагает направление камеры вниз на плоскость. Свойства камеры можно изменить, установив уровень масштабирования, область просмотра или перспективу карты. Дополнительные сведения вы найдете в руководстве по работе с камерой. Пользователи также могут управлять камерой с помощью жестов.
С помощью прослушивателей вы можете получать сведения о перемещении камеры. Ваше приложение может получать уведомления для событий начала, продолжения и окончания движения камеры. Вы сможете также увидеть, почему камера движется, независимо от того, чем это вызвано – жестами пользователя, встроенной анимацией API или движениями, которые контролируются разработчиками.
Следующий образец демонстрирует все доступные прослушиватели для событий камеры:
Java
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.example.mapdemo; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.CompoundButton; import android.widget.SeekBar; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.CancelableCallback; import com.google.android.gms.maps.GoogleMap.OnCameraIdleListener; import com.google.android.gms.maps.GoogleMap.OnCameraMoveCanceledListener; import com.google.android.gms.maps.GoogleMap.OnCameraMoveListener; import com.google.android.gms.maps.GoogleMap.OnCameraMoveStartedListener; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.PolylineOptions; /** * This shows how to change the camera position for the map. */ public class CameraDemoActivity extends AppCompatActivity implements OnCameraMoveStartedListener, OnCameraMoveListener, OnCameraMoveCanceledListener, OnCameraIdleListener, OnMapReadyCallback { private static final String TAG = CameraDemoActivity.class.getName(); /** * The amount by which to scroll the camera. Note that this amount is in raw pixels, not dp * (density-independent pixels). */ private static final int SCROLL_BY_PX = 100; public static final CameraPosition BONDI = new CameraPosition.Builder().target(new LatLng(-33.891614, 151.276417)) .zoom(15.5f) .bearing(300) .tilt(50) .build(); public static final CameraPosition SYDNEY = new CameraPosition.Builder().target(new LatLng(-33.87365, 151.20689)) .zoom(15.5f) .bearing(0) .tilt(25) .build(); private GoogleMap map; private CompoundButton animateToggle; private CompoundButton customDurationToggle; private SeekBar customDurationBar; private PolylineOptions currPolylineOptions; private boolean isCanceled = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.camera_demo); animateToggle = findViewById(R.id.animate); customDurationToggle = findViewById(R.id.duration_toggle); customDurationBar = findViewById(R.id.duration_bar); updateEnabledState(); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); } @Override protected void onResume() { super.onResume(); updateEnabledState(); } @Override public void onMapReady(GoogleMap googleMap) { map = googleMap; map.setOnCameraIdleListener(this); map.setOnCameraMoveStartedListener(this); map.setOnCameraMoveListener(this); map.setOnCameraMoveCanceledListener(this); // We will provide our own zoom controls. map.getUiSettings().setZoomControlsEnabled(false); map.getUiSettings().setMyLocationButtonEnabled(true); // Show Sydney map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-33.87365, 151.20689), 10)); } /** * When the map is not ready the CameraUpdateFactory cannot be used. This should be called on * all entry points that call methods on the Google Maps API. */ private boolean checkReady() { if (map == null) { Toast.makeText(this, R.string.map_not_ready, Toast.LENGTH_SHORT).show(); return false; } return true; } /** * Called when the Go To Bondi button is clicked. */ public void onGoToBondi(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.newCameraPosition(BONDI)); } /** * Called when the Animate To Sydney button is clicked. */ public void onGoToSydney(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.newCameraPosition(SYDNEY), new CancelableCallback() { @Override public void onFinish() { Toast.makeText(getBaseContext(), "Animation to Sydney complete", Toast.LENGTH_SHORT) .show(); } @Override public void onCancel() { Toast.makeText(getBaseContext(), "Animation to Sydney canceled", Toast.LENGTH_SHORT) .show(); } }); } /** * Called when the stop button is clicked. */ public void onStopAnimation(View view) { if (!checkReady()) { return; } map.stopAnimation(); } /** * Called when the zoom in button (the one with the +) is clicked. */ public void onZoomIn(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.zoomIn()); } /** * Called when the zoom out button (the one with the -) is clicked. */ public void onZoomOut(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.zoomOut()); } /** * Called when the tilt more button (the one with the /) is clicked. */ public void onTiltMore(View view) { if (!checkReady()) { return; } CameraPosition currentCameraPosition = map.getCameraPosition(); float currentTilt = currentCameraPosition.tilt; float newTilt = currentTilt + 10; newTilt = (newTilt > 90) ? 90 : newTilt; CameraPosition cameraPosition = new CameraPosition.Builder(currentCameraPosition) .tilt(newTilt).build(); changeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } /** * Called when the tilt less button (the one with the \) is clicked. */ public void onTiltLess(View view) { if (!checkReady()) { return; } CameraPosition currentCameraPosition = map.getCameraPosition(); float currentTilt = currentCameraPosition.tilt; float newTilt = currentTilt - 10; newTilt = (newTilt > 0) ? newTilt : 0; CameraPosition cameraPosition = new CameraPosition.Builder(currentCameraPosition) .tilt(newTilt).build(); changeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } /** * Called when the left arrow button is clicked. This causes the camera to move to the left */ public void onScrollLeft(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.scrollBy(-SCROLL_BY_PX, 0)); } /** * Called when the right arrow button is clicked. This causes the camera to move to the right. */ public void onScrollRight(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.scrollBy(SCROLL_BY_PX, 0)); } /** * Called when the up arrow button is clicked. The causes the camera to move up. */ public void onScrollUp(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.scrollBy(0, -SCROLL_BY_PX)); } /** * Called when the down arrow button is clicked. This causes the camera to move down. */ public void onScrollDown(View view) { if (!checkReady()) { return; } changeCamera(CameraUpdateFactory.scrollBy(0, SCROLL_BY_PX)); } /** * Called when the animate button is toggled */ public void onToggleAnimate(View view) { updateEnabledState(); } /** * Called when the custom duration checkbox is toggled */ public void onToggleCustomDuration(View view) { updateEnabledState(); } /** * Update the enabled state of the custom duration controls. */ private void updateEnabledState() { customDurationToggle.setEnabled(animateToggle.isChecked()); customDurationBar .setEnabled(animateToggle.isChecked() && customDurationToggle.isChecked()); } private void changeCamera(CameraUpdate update) { changeCamera(update, null); } /** * Change the camera position by moving or animating the camera depending on the state of the * animate toggle button. */ private void changeCamera(CameraUpdate update, CancelableCallback callback) { if (animateToggle.isChecked()) { if (customDurationToggle.isChecked()) { int duration = customDurationBar.getProgress(); // The duration must be strictly positive so we make it at least 1. map.animateCamera(update, Math.max(duration, 1), callback); } else { map.animateCamera(update, callback); } } else { map.moveCamera(update); } } @Override public void onCameraMoveStarted(int reason) { if (!isCanceled) { map.clear(); } String reasonText = "UNKNOWN_REASON"; currPolylineOptions = new PolylineOptions().width(5); switch (reason) { case OnCameraMoveStartedListener.REASON_GESTURE: currPolylineOptions.color(Color.BLUE); reasonText = "GESTURE"; break; case OnCameraMoveStartedListener.REASON_API_ANIMATION: currPolylineOptions.color(Color.RED); reasonText = "API_ANIMATION"; break; case OnCameraMoveStartedListener.REASON_DEVELOPER_ANIMATION: currPolylineOptions.color(Color.GREEN); reasonText = "DEVELOPER_ANIMATION"; break; } Log.d(TAG, "onCameraMoveStarted(" + reasonText + ")"); addCameraTargetToPath(); } @Override public void onCameraMove() { // When the camera is moving, add its target to the current path we'll draw on the map. if (currPolylineOptions != null) { addCameraTargetToPath(); } Log.d(TAG, "onCameraMove"); } @Override public void onCameraMoveCanceled() { // When the camera stops moving, add its target to the current path, and draw it on the map. if (currPolylineOptions != null) { addCameraTargetToPath(); map.addPolyline(currPolylineOptions); } isCanceled = true; // Set to clear the map when dragging starts again. currPolylineOptions = null; Log.d(TAG, "onCameraMoveCancelled"); } @Override public void onCameraIdle() { if (currPolylineOptions != null) { addCameraTargetToPath(); map.addPolyline(currPolylineOptions); } currPolylineOptions = null; isCanceled = false; // Set to *not* clear the map when dragging starts again. Log.d(TAG, "onCameraIdle"); } private void addCameraTargetToPath() { LatLng target = map.getCameraPosition().target; currPolylineOptions.add(target); } }
Kotlin
/* * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.kotlindemos import android.graphics.Color import android.os.Bundle import android.util.Log import android.view.View import android.widget.CompoundButton import android.widget.SeekBar import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.maps.CameraUpdate import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.GoogleMap.CancelableCallback import com.google.android.gms.maps.GoogleMap.OnCameraIdleListener import com.google.android.gms.maps.GoogleMap.OnCameraMoveCanceledListener import com.google.android.gms.maps.GoogleMap.OnCameraMoveListener import com.google.android.gms.maps.GoogleMap.OnCameraMoveStartedListener import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.CameraPosition import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.PolylineOptions /** * This shows how to change the camera position for the map. */ class CameraDemoActivity : AppCompatActivity(), OnCameraMoveStartedListener, OnCameraMoveListener, OnCameraMoveCanceledListener, OnCameraIdleListener, OnMapReadyCallback { /** * The amount by which to scroll the camera. Note that this amount is in raw pixels, not dp * (density-independent pixels). */ private val SCROLL_BY_PX = 100 private val TAG = CameraDemoActivity::class.java.name private val sydneyLatLng = LatLng(-33.87365, 151.20689) private val bondiLocation: CameraPosition = CameraPosition.Builder() .target(LatLng(-33.891614, 151.276417)) .zoom(15.5f) .bearing(300f) .tilt(50f) .build() private val sydneyLocation: CameraPosition = CameraPosition.Builder(). target(LatLng(-33.87365, 151.20689)) .zoom(15.5f) .bearing(0f) .tilt(25f) .build() private lateinit var map: GoogleMap private lateinit var animateToggle: CompoundButton private lateinit var customDurationToggle: CompoundButton private lateinit var customDurationBar: SeekBar private var currPolylineOptions: PolylineOptions? = null private var isCanceled = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.camera_demo) animateToggle = findViewById(R.id.animate) customDurationToggle = findViewById(R.id.duration_toggle) customDurationBar = findViewById(R.id.duration_bar) updateEnabledState() val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) } override fun onResume() { super.onResume() updateEnabledState() } override fun onMapReady(googleMap: GoogleMap) { map = googleMap // return early if the map was not initialised properly with(googleMap) { setOnCameraIdleListener(this@CameraDemoActivity) setOnCameraMoveStartedListener(this@CameraDemoActivity) setOnCameraMoveListener(this@CameraDemoActivity) setOnCameraMoveCanceledListener(this@CameraDemoActivity) // We will provide our own zoom controls. uiSettings.isZoomControlsEnabled = false uiSettings.isMyLocationButtonEnabled = true // Show Sydney moveCamera(CameraUpdateFactory.newLatLngZoom(sydneyLatLng, 10f)) } } /** * When the map is not ready the CameraUpdateFactory cannot be used. This should be used to wrap * all entry points that call methods on the Google Maps API. * * @param stuffToDo the code to be executed if the map is initialised */ private fun checkReadyThen(stuffToDo: () -> Unit) { if (!::map.isInitialized) { Toast.makeText(this, R.string.map_not_ready, Toast.LENGTH_SHORT).show() } else { stuffToDo() } } /** * Called when the Go To Bondi button is clicked. */ @Suppress("UNUSED_PARAMETER") fun onGoToBondi(view: View) { checkReadyThen { changeCamera(CameraUpdateFactory.newCameraPosition(bondiLocation)) } } /** * Called when the Animate To Sydney button is clicked. */ @Suppress("UNUSED_PARAMETER") fun onGoToSydney(view: View) { checkReadyThen { changeCamera(CameraUpdateFactory.newCameraPosition(sydneyLocation), object : CancelableCallback { override fun onFinish() { Toast.makeText(baseContext, "Animation to Sydney complete", Toast.LENGTH_SHORT).show() } override fun onCancel() { Toast.makeText(baseContext, "Animation to Sydney canceled", Toast.LENGTH_SHORT).show() } }) } } /** * Called when the stop button is clicked. */ @Suppress("UNUSED_PARAMETER") fun onStopAnimation(view: View) = checkReadyThen { map.stopAnimation() } /** * Called when the zoom in button (the one with the +) is clicked. */ @Suppress("UNUSED_PARAMETER") fun onZoomIn(view: View) = checkReadyThen { changeCamera(CameraUpdateFactory.zoomIn()) } /** * Called when the zoom out button (the one with the -) is clicked. */ @Suppress("UNUSED_PARAMETER") fun onZoomOut(view: View) = checkReadyThen { changeCamera(CameraUpdateFactory.zoomOut()) } /** * Called when the tilt more button (the one with the /) is clicked. */ @Suppress("UNUSED_PARAMETER") fun onTiltMore(view: View) { checkReadyThen { val newTilt = Math.min(map.cameraPosition.tilt + 10, 90F) val cameraPosition = CameraPosition.Builder(map.cameraPosition).tilt(newTilt).build() changeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)) } } /** * Called when the tilt less button (the one with the \) is clicked. */ @Suppress("UNUSED_PARAMETER") fun onTiltLess(view: View) { checkReadyThen { val newTilt = Math.max(map.cameraPosition.tilt - 10, 0F) val cameraPosition = CameraPosition.Builder(map.cameraPosition).tilt(newTilt).build() changeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)) } } /** * Called when the left arrow button is clicked. This causes the camera to move to the left */ @Suppress("UNUSED_PARAMETER") fun onScrollLeft(view: View) { checkReadyThen { changeCamera(CameraUpdateFactory.scrollBy((-SCROLL_BY_PX).toFloat(),0f)) } } /** * Called when the right arrow button is clicked. This causes the camera to move to the right. */ @Suppress("UNUSED_PARAMETER") fun onScrollRight(view: View) { checkReadyThen { changeCamera(CameraUpdateFactory.scrollBy(SCROLL_BY_PX.toFloat(), 0f)) } } /** * Called when the up arrow button is clicked. The causes the camera to move up. */ @Suppress("UNUSED_PARAMETER") fun onScrollUp(view: View) { checkReadyThen { changeCamera(CameraUpdateFactory.scrollBy(0f, (-SCROLL_BY_PX).toFloat())) } } /** * Called when the down arrow button is clicked. This causes the camera to move down. */ @Suppress("UNUSED_PARAMETER") fun onScrollDown(view: View) { checkReadyThen { changeCamera(CameraUpdateFactory.scrollBy(0f, SCROLL_BY_PX.toFloat())) } } /** * Called when the animate button is toggled */ @Suppress("UNUSED_PARAMETER") fun onToggleAnimate(view: View) = updateEnabledState() /** * Called when the custom duration checkbox is toggled */ @Suppress("UNUSED_PARAMETER") fun onToggleCustomDuration(view: View) = updateEnabledState() /** * Update the enabled state of the custom duration controls. */ private fun updateEnabledState() { customDurationToggle.isEnabled = animateToggle.isChecked customDurationBar.isEnabled = animateToggle.isChecked && customDurationToggle.isChecked } /** * Change the camera position by moving or animating the camera depending on the state of the * animate toggle button. */ private fun changeCamera(update: CameraUpdate, callback: CancelableCallback? = null) { if (animateToggle.isChecked) { if (customDurationToggle.isChecked) { // The duration must be strictly positive so we make it at least 1. map.animateCamera(update, Math.max(customDurationBar.progress, 1), callback) } else { map.animateCamera(update, callback) } } else { map.moveCamera(update) } } override fun onCameraMoveStarted(reason: Int) { if (!isCanceled) map.clear() var reasonText = "UNKNOWN_REASON" currPolylineOptions = PolylineOptions().width(5f) when (reason) { OnCameraMoveStartedListener.REASON_GESTURE -> { currPolylineOptions?.color(Color.BLUE) reasonText = "GESTURE" } OnCameraMoveStartedListener.REASON_API_ANIMATION -> { currPolylineOptions?.color(Color.RED) reasonText = "API_ANIMATION" } OnCameraMoveStartedListener.REASON_DEVELOPER_ANIMATION -> { currPolylineOptions?.color(Color.GREEN) reasonText = "DEVELOPER_ANIMATION" } } Log.d(TAG, "onCameraMoveStarted($reasonText)") addCameraTargetToPath() } /** * Ensures that currPolyLine options is not null before accessing it * * @param stuffToDo the code to be executed if currPolylineOptions is not null */ private fun checkPolylineThen(stuffToDo: () -> Unit) { if (currPolylineOptions != null) stuffToDo() } override fun onCameraMove() { Log.d(TAG, "onCameraMove") // When the camera is moving, add its target to the current path we'll draw on the map. checkPolylineThen { addCameraTargetToPath() } } override fun onCameraMoveCanceled() { // When the camera stops moving, add its target to the current path, and draw it on the map. checkPolylineThen { addCameraTargetToPath() map.addPolyline(currPolylineOptions!!) } isCanceled = true // Set to clear the map when dragging starts again. currPolylineOptions = null Log.d(TAG, "onCameraMoveCancelled") } override fun onCameraIdle() { checkPolylineThen { addCameraTargetToPath() map.addPolyline(currPolylineOptions!!) } currPolylineOptions = null isCanceled = false // Set to *not* clear the map when dragging starts again. Log.d(TAG, "onCameraIdle") } private fun addCameraTargetToPath() { currPolylineOptions?.add(map.cameraPosition.target) } }
Предусмотрены следующие прослушиватели камеры:
Обратный вызов метода
onCameraMoveStarted()
для прослушивателяOnCameraMoveStartedListener
выполняется, когда камера начинает движение. Метод обратного вызова получает константуreason
, указывающую причину движения камеры. Причина может быть одной из следующих:REASON_GESTURE
указывает, что камера начала движение в ответ на жест пользователя на карте, такой как панорамирование, наклон, вращение карты, сведение или разведение пальцев для масштабирования.REASON_API_ANIMATION
указывает, что API вызвал движение камеры в ответ на действие пользователя, не связанное с жестами, такое как нажатие кнопки масштабирования, кнопки "Мое местоположение" или касание маркера.REASON_DEVELOPER_ANIMATION
указывает, что движение камеры инициировано приложением.
Обратный вызов метода
onCameraMove()
для прослушивателяOnCameraMoveListener
выполняется несколько раз во время движения камеры или при действиях пользователя на сенсорном экране. Полезно знать, что API выполняет обратный вызов один раз для каждого фрейма. Тем не менее обратите внимание, что этот обратный вызов выполняется асинхронно и, следовательно, не будет синхронизирован с текущим отображением экрана. Кроме того, следует учитывать, что камера может не изменять свое положение между двумя обратными вызовами методаonCameraMove()
.Обратный вызов метода
OnCameraIdle()
для прослушивателяOnCameraIdleListener
происходит, когда камера прекращает движение, а пользователь не выполняет никаких действий с картой.Обратный вызов метода
OnCameraMoveCanceled()
для прослушивателяOnCameraMoveCanceledListener
происходит, когда текущее движение камеры было прервано. Сразу же после обратного вызова методаOnCameraMoveCanceled()
выполняется обратный вызов методаonCameraMoveStarted()
с новым параметромreason
.Если ваше приложение явным образом вызывает метод
GoogleMap.stopAnimation()
, выполняется обратный вызов методаOnCameraMoveCanceled()
, но при этом обратный вызовonCameraMoveStarted()
не происходит.
Чтобы добавить прослушиватель на карту, необходимо вызвать соответствующий метод.
Например, для запроса обратного вызова из прослушивателя OnCameraMoveStartedListener
вызовите метод GoogleMap.setOnCameraMoveStartedListener()
.
Вы можете получить целевой объект камеры (широту и долготу), масштаб, направление и наклон из объекта CameraPosition
. Дополнительную информацию об этом вы найдете в руководстве по положению камеры.
События, связанные с организациями и другими объектами
По умолчанию объекты инфраструктуры отображаются на базовой карте вместе с соответствующими значками. К объектам относятся парки, школы, правительственные здания и прочее, а также коммерческие организации, такие как магазины, рестораны и гостиницы.
Вы можете обрабатывать события кликов для объектов. Ознакомьтесь с руководством по работе с компаниями и другими объектами.
События со схемами зданий
События можно использовать для поиска и настройки активного уровня схемы здания. Используйте интерфейс OnIndoorStateChangeListener
, чтобы настроить вызов прослушивателя, когда в фокус попадает новое здание или активируется новый уровень в нем.
Чтобы получить данные о здании, которое в настоящий момент находится в фокусе, вызовите GoogleMap.getFocusedBuilding()
.
Центрирование карты на определенной широте или долготе обычно позволяет получить информацию о здании по этим координатам, однако это не гарантируется.
После этого вы можете найти текущий активный уровень, вызвав метод IndoorBuilding.getActiveLevelIndex()
.
Java
IndoorBuilding building = map.getFocusedBuilding(); if (building != null) { int activeLevelIndex = building.getActiveLevelIndex(); IndoorLevel activeLevel = building.getLevels().get(activeLevelIndex); }
Kotlin
map.focusedBuilding?.let { building: IndoorBuilding -> val activeLevelIndex = building.activeLevelIndex val activeLevel = building.levels[activeLevelIndex] }
Это применяется для отображения пользовательской разметки активного уровня, такой как маркеры, наземные наложения, фрагментные наложения, многоугольники, ломаные линии и другие фигуры.
Совет. Чтобы вернуться на уровень улицы, получите уровень по умолчанию с помощью метода IndoorBuilding.getDefaultLevelIndex()
и установите его в качестве активного с помощью метода IndoorLevel.activate()
.
События для маркера и информационного окна
Вы можете отслеживать события маркера, включая его клики и перетаскивания, и реагировать на них, установив соответствующий прослушиватель для объекта GoogleMap
, которому принадлежит этот маркер. Ознакомьтесь с руководством по событиям для маркера.
Вы также можете отслеживать события для информационных окон.
События для форм и наложений
Вы можете прослушивать события кликов для ломаных линий, многоугольников, кругов и наземных наложений, а также реагировать на эти события.
События для местоположения
Ваше приложение может реагировать на перечисленные ниже события, связанные со слоем "Мое местоположение":
- Если пользователь нажимает кнопку "Мое местоположение", ваше приложение получает обратный вызов
onMyLocationButtonClick()
от прослушивателяGoogleMap.OnMyLocationButtonClickListener
. - Если пользователь нажимает на синюю точку "Мое местоположение", ваше приложение получает обратный вызов
onMyLocationClick()
от прослушивателяGoogleMap.OnMyLocationClickListener
.
Подробную информацию вы найдете в руководстве по работе со слоем "Мое местоположение".