เมื่อใช้ Maps SDK สําหรับ Android คุณจะฟังเหตุการณ์บนแผนที่ได้
ตัวอย่างโค้ด
ที่เก็บ ApiDemos ใน GitHub มีตัวอย่างที่แสดงเหตุการณ์และผู้ฟัง ดังนี้
Kotlin
- EventsDemoActivity: แมปเหตุการณ์การคลิกและการเปลี่ยนแปลงกล้อง
- CameraDemoActivity: เหตุการณ์การเปลี่ยนแปลงของกล้อง
- CircleDemoActivity: เหตุการณ์การคลิกและลากเครื่องหมาย
- GroundOverlayDemoActivity: เหตุการณ์การคลิกการวางซ้อนพื้น
- IndoorDemoActivity: เหตุการณ์แผนที่ในอาคาร
- MarkerDemoActivity: เหตุการณ์เครื่องหมายและหน้าต่างข้อมูล
- PolygonDemoActivity: เหตุการณ์ Polygon
Java
- EventsDemoActivity: แมปเหตุการณ์การคลิกและการเปลี่ยนแปลงกล้อง
- CameraDemoActivity: เหตุการณ์การเปลี่ยนแปลงของกล้อง
- CircleDemoActivity: เหตุการณ์การคลิกและลากเครื่องหมาย
- GroundOverlayDemoActivity: เหตุการณ์การคลิกการวางซ้อนพื้น
- IndoorDemoActivity: เหตุการณ์แผนที่ในอาคาร
- MarkerDemoActivity: เหตุการณ์เครื่องหมายและหน้าต่างข้อมูล
- PolygonDemoActivity: เหตุการณ์ Polygon
แมปเหตุการณ์การคลิก / การคลิกค้าง
หากต้องการตอบสนองต่อผู้ใช้ที่แตะจุดบนแผนที่ ให้ใช้ OnMapClickListener
ซึ่งคุณตั้งค่าบนแผนที่ได้โดยเรียกใช้ GoogleMap.setOnMapClickListener(OnMapClickListener)
เมื่อผู้ใช้คลิก (แตะ) ที่ใดก็ตามบนแผนที่ คุณจะได้รับonMapClick(LatLng)
เหตุการณ์ที่ระบุตําแหน่งในแผนที่ที่ผู้ใช้คลิก โปรดทราบว่าหากต้องการตำแหน่งที่สอดคล้องกับตำแหน่งบนหน้าจอ (เป็นพิกเซล) คุณสามารถรับ Projection
จากแผนที่ ซึ่งจะช่วยให้คุณแปลงระหว่างพิกัดละติจูด/ลองจิจูดกับพิกัดพิกเซลของหน้าจอได้
นอกจากนี้ คุณยังคอยฟังเหตุการณ์การคลิกค้างไว้ได้ด้วย OnMapLongClickListener
ซึ่งตั้งค่าได้ในแผนที่โดยเรียกใช้ GoogleMap.setOnMapLongClickListener(OnMapLongClickListener)
Listener นี้ทํางานคล้ายกับ Listener การคลิกและจะได้รับการแจ้งเตือนเมื่อเกิดเหตุการณ์การคลิกค้างไว้ด้วย onMapLongClick(LatLng)
callback
การปิดใช้เหตุการณ์การคลิกในโหมด Lite
หากต้องการปิดใช้เหตุการณ์การคลิกบนแผนที่ในโหมด Lite ให้เรียกใช้ setClickable()
ในมุมมองที่มี MapView
หรือ MapFragment
ซึ่งมีประโยชน์ เช่น เมื่อแสดงแผนที่หรือแผนที่ในมุมมองรายการที่คุณต้องการให้เหตุการณ์การคลิกเรียกการดำเนินการที่ไม่เกี่ยวข้องกับแผนที่
ตัวเลือกในการปิดใช้เหตุการณ์คลิกจะใช้ได้เฉพาะในโหมด Lite เท่านั้น การปิดใช้เหตุการณ์การคลิกจะทำให้เครื่องหมายคลิกไม่ได้ด้วย การดำเนินการนี้จะไม่ส่งผลต่อการควบคุมอื่นๆ ในแผนที่
สำหรับ MapView
Kotlin
val mapView = findViewById<MapView>(R.id.mapView) mapView.isClickable = false
Java
MapView mapView = findViewById(R.id.mapView); mapView.setClickable(false);
สำหรับ MapFragment
Kotlin
val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment val view = mapFragment.view view?.isClickable = false
Java
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); View view = mapFragment.getView(); view.setClickable(false);
เหตุการณ์การเปลี่ยนแปลงของกล้อง
มุมมองแผนที่จะจำลองเป็นกล้องที่มองลงมาบนพื้นผิวเรียบ คุณสามารถเปลี่ยนคุณสมบัติของกล้องเพื่อส่งผลต่อระดับการซูม พอร์ตดู และมุมมองของแผนที่ได้ ดูคู่มือเกี่ยวกับกล้อง นอกจากนี้ ผู้ใช้ยังควบคุมกล้องได้ด้วยท่าทางสัมผัส
คุณติดตามการเคลื่อนไหวของกล้องได้โดยใช้ Listeners สำหรับการเปลี่ยนแปลงของกล้อง แอปของคุณจะได้รับการแจ้งเตือนสำหรับเหตุการณ์เริ่มต้น ต่อเนื่อง และสิ้นสุดการเคลื่อนไหวของกล้อง นอกจากนี้ คุณยังดูสาเหตุที่กล้องเคลื่อนไหวได้ด้วย ไม่ว่าจะเป็นการเคลื่อนไหวที่เกิดจากท่าทางสัมผัสของผู้ใช้ ภาพเคลื่อนไหว API ในตัว หรือการเคลื่อนไหวที่นักพัฒนาแอปควบคุม
ตัวอย่างต่อไปนี้แสดงตัวรับฟังเหตุการณ์ของกล้องทั้งหมดที่ใช้ได้
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) } }
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); } }
เครื่องมือฟังเสียงจากกล้องที่ใช้ได้มีดังนี้
ระบบจะเรียกใช้
onCameraMoveStarted()
callback ของOnCameraMoveStartedListener
เมื่อกล้องเริ่มเคลื่อนไหว เมธอด Callback จะได้รับreason
สำหรับการเคลื่อนไหวของกล้อง สาเหตุอาจเป็นอย่างใดอย่างหนึ่งต่อไปนี้REASON_GESTURE
บ่งบอกว่ากล้องเคลื่อนไหวตามท่าทางสัมผัสของผู้ใช้บนแผนที่ เช่น การแพน การเอียง การบีบนิ้วเพื่อซูม หรือการหมุนแผนที่REASON_API_ANIMATION
บ่งบอกว่า API ได้ย้ายกล้องเพื่อตอบสนองต่อการกระทำของผู้ใช้ที่ไม่ใช่ท่าทางสัมผัส เช่น การแตะปุ่มซูม การแตะปุ่ม "ตำแหน่งของฉัน" หรือการคลิกเครื่องหมายREASON_DEVELOPER_ANIMATION
บ่งบอกว่าแอปของคุณได้เริ่มการเคลื่อนไหวของกล้องแล้ว
ระบบเรียกใช้
onCameraMove()
callback ของOnCameraMoveListener
หลายครั้งขณะที่กล้องเคลื่อนไหวหรือผู้ใช้โต้ตอบกับหน้าจอสัมผัส ข้อมูลว่า API จะเรียกใช้การเรียกกลับ 1 ครั้งต่อเฟรมจะเป็นประโยชน์ในการใช้เป็นแนวทางเกี่ยวกับความถี่ในการเรียกใช้การเรียกกลับ อย่างไรก็ตาม โปรดทราบว่าระบบจะเรียกใช้การเรียกกลับนี้แบบไม่พร้อมกัน ดังนั้นจึงไม่ได้ซิงค์กับสิ่งที่ปรากฏบนหน้าจอ นอกจากนี้ โปรดทราบว่าตำแหน่งของกล้องอาจไม่มีการเปลี่ยนแปลงระหว่างonCameraMove()
การเรียกกลับครั้งหนึ่งกับครั้งถัดไประบบจะเรียกใช้
OnCameraIdle()
callback ของOnCameraIdleListener
เมื่อกล้องหยุดเคลื่อนไหวและผู้ใช้หยุดโต้ตอบกับแผนที่ระบบจะเรียกใช้
OnCameraMoveCanceled()
callback ของOnCameraMoveCanceledListener
เมื่อการเคลื่อนไหวของกล้องปัจจุบันถูกขัดจังหวะ ทันทีหลังจากการเรียกกลับOnCameraMoveCanceled()
ระบบจะเรียกใช้การเรียกกลับonCameraMoveStarted()
ด้วยreason
ใหม่หากแอปเรียกใช้
GoogleMap.stopAnimation()
อย่างชัดเจน ระบบจะเรียกใช้การเรียกคืนOnCameraMoveCanceled()
แต่ไม่เรียกใช้การเรียกคืนonCameraMoveStarted()
หากต้องการตั้งค่า Listener ในแผนที่ ให้เรียกใช้เมธอด set-listener ที่เกี่ยวข้อง
ตัวอย่างเช่น หากต้องการขอให้ OnCameraMoveStartedListener
โทรกลับ ให้โทรไปที่
GoogleMap.setOnCameraMoveStartedListener()
คุณดูเป้าหมาย (ละติจูด/ลองจิจูด) การซูม ทิศทาง และการเอียงของกล้องได้จาก CameraPosition
ดูรายละเอียดเกี่ยวกับพร็อพเพอร์ตี้เหล่านี้ได้ในคำแนะนำเกี่ยวกับตำแหน่งกล้อง
กิจกรรมในธุรกิจและจุดที่น่าสนใจอื่นๆ
โดยค่าเริ่มต้น จุดที่น่าสนใจ (จุดที่น่าสนใจ) จะปรากฏบนแผนที่ฐานพร้อมกับไอคอนที่เกี่ยวข้อง ซึ่งได้แก่ สวนสาธารณะ โรงเรียน อาคารรัฐ และอื่นๆ รวมถึงจุดที่น่าสนใจทางธุรกิจ เช่น ร้านค้า ร้านอาหาร และโรงแรม
คุณตอบสนองต่อเหตุการณ์การคลิกในจุดที่น่าสนใจได้ ดูคู่มือเกี่ยวกับธุรกิจและสถานที่น่าสนใจอื่นๆ
กิจกรรมในแผนที่ในอาคาร
คุณสามารถใช้เหตุการณ์เพื่อค้นหาและปรับแต่งระดับที่ใช้งานอยู่ของแผนที่ในอาคารได้ ใช้อินเทอร์เฟซ OnIndoorStateChangeListener
เพื่อตั้งค่าให้เรียกฟังเมื่อโฟกัสอาคารใหม่หรือเปิดใช้งานชั้นใหม่ในอาคาร
ค้นหาอาคารที่โฟกัสอยู่ในปัจจุบันโดยโทรไปที่ GoogleMap.getFocusedBuilding()
โดยปกติแล้ว การทำให้แผนที่เป็นศูนย์กลางของละติจูด/ลองจิจูดที่เฉพาะเจาะจงจะแสดงอาคารที่ละติจูด/ลองจิจูดนั้น แต่เราไม่รับประกัน
จากนั้นคุณจะเห็นระดับที่ใช้งานอยู่ในปัจจุบันโดยเรียกใช้ IndoorBuilding.getActiveLevelIndex()
Kotlin
map.focusedBuilding?.let { building: IndoorBuilding -> val activeLevelIndex = building.activeLevelIndex val activeLevel = building.levels[activeLevelIndex] }
Java
IndoorBuilding building = map.getFocusedBuilding(); if (building != null) { int activeLevelIndex = building.getActiveLevelIndex(); IndoorLevel activeLevel = building.getLevels().get(activeLevelIndex); }
ซึ่งมีประโยชน์ในกรณีที่คุณต้องการแสดงมาร์กอัปที่กําหนดเองสําหรับระดับที่ใช้งานอยู่ เช่น เครื่องหมาย การวางซ้อนพื้นดิน การวางซ้อนไทล์ รูปหลายเหลี่ยม เส้นประกอบ และรูปร่างอื่นๆ
เคล็ดลับ: หากต้องการกลับไปที่ระดับถนน ให้รับระดับเริ่มต้นผ่าน
IndoorBuilding.getDefaultLevelIndex()
แล้วตั้งเป็นระดับที่ใช้งานอยู่ผ่าน
IndoorLevel.activate()
เหตุการณ์เครื่องหมายและหน้าต่างข้อมูล
คุณสามารถรับฟังและตอบสนองต่อเหตุการณ์ของเครื่องหมาย ซึ่งรวมถึงเหตุการณ์การคลิกและการลากเครื่องหมาย โดยการตั้งค่า Listener ที่เกี่ยวข้องบนออบเจ็กต์ GoogleMap
ที่เป็นของเคอร์เซอร์ ดูคู่มือเหตุการณ์เครื่องหมาย
นอกจากนี้ คุณยังฟังเหตุการณ์ในหน้าต่างข้อมูลได้ด้วย
รูปร่างและเหตุการณ์วางซ้อน
คุณสามารถฟังและตอบสนองต่อเหตุการณ์การคลิกในเส้นประกอบ รูปหลายเหลี่ยม วงกลม และการวางซ้อนพื้นดิน
เหตุการณ์เกี่ยวกับสถานที่
แอปสามารถตอบสนองต่อเหตุการณ์ต่อไปนี้ที่เกี่ยวข้องกับเลเยอร์ตำแหน่งของฉัน
- หากผู้ใช้คลิกปุ่ม "ตำแหน่งของฉัน" แอปของคุณจะได้รับ
onMyLocationButtonClick()
การเรียกกลับจากGoogleMap.OnMyLocationButtonClickListener
- หากผู้ใช้คลิกจุดสีน้ำเงิน "ตำแหน่งของฉัน" แอปของคุณจะได้รับ
onMyLocationClick()
การเรียกกลับจากGoogleMap.OnMyLocationClickListener
โปรดดูรายละเอียดที่คู่มือเลเยอร์ตำแหน่งของฉัน