Hướng dẫn này chỉ cho bạn cách thêm bản đồ Google vào ứng dụng Android và sử dụng hình nhiều đường và đa giác để biểu thị tuyến đường và khu vực trên bản đồ.
Làm theo hướng dẫn để tạo một ứng dụng Android bằng SDK Bản đồ dành cho Android. Môi trường phát triển được đề xuất là Android Studio.
Lấy mã
Sao chép hoặc tải kho lưu trữ Mẫu API phiên bản 2 của Google Maps cho Android trên GitHub.
Xem phiên bản Java của hoạt động:
// 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.polygons; import android.os.Bundle; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CustomCap; import com.google.android.gms.maps.model.Dash; import com.google.android.gms.maps.model.Dot; import com.google.android.gms.maps.model.Gap; import com.google.android.gms.maps.model.JointType; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.PatternItem; import com.google.android.gms.maps.model.Polygon; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.RoundCap; import java.util.Arrays; import java.util.List; /** * An activity that displays a Google map with polylines to represent paths or routes, * and polygons to represent areas. */ public class PolyActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnPolylineClickListener, GoogleMap.OnPolygonClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ @Override public void onMapReady(GoogleMap googleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.setTag("A"); // Style the polyline. stylePolyline(polyline1); Polyline polyline2 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-29.501, 119.700), new LatLng(-27.456, 119.672), new LatLng(-25.971, 124.187), new LatLng(-28.081, 126.555), new LatLng(-28.848, 124.229), new LatLng(-28.215, 123.938))); polyline2.setTag("B"); stylePolyline(polyline2); // Add polygons to indicate areas on the map. Polygon polygon1 = googleMap.addPolygon(new PolygonOptions() .clickable(true) .add( new LatLng(-27.457, 153.040), new LatLng(-33.852, 151.211), new LatLng(-37.813, 144.962), new LatLng(-34.928, 138.599))); // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.setTag("alpha"); // Style the polygon. stylePolygon(polygon1); Polygon polygon2 = googleMap.addPolygon(new PolygonOptions() .clickable(true) .add( new LatLng(-31.673, 128.892), new LatLng(-31.952, 115.857), new LatLng(-17.785, 122.258), new LatLng(-12.4258, 130.7932))); polygon2.setTag("beta"); stylePolygon(polygon2); // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.684, 133.903), 4)); // Set listeners for click events. googleMap.setOnPolylineClickListener(this); googleMap.setOnPolygonClickListener(this); } private static final int COLOR_BLACK_ARGB = 0xff000000; private static final int POLYLINE_STROKE_WIDTH_PX = 12; /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private void stylePolyline(Polyline polyline) { String type = ""; // Get the data object stored with the polyline. if (polyline.getTag() != null) { type = polyline.getTag().toString(); } switch (type) { // If no type is given, allow the API to use the default. case "A": // Use a custom bitmap as the cap at the start of the line. polyline.setStartCap( new CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10)); break; case "B": // Use a round cap at the start of the line. polyline.setStartCap(new RoundCap()); break; } polyline.setEndCap(new RoundCap()); polyline.setWidth(POLYLINE_STROKE_WIDTH_PX); polyline.setColor(COLOR_BLACK_ARGB); polyline.setJointType(JointType.ROUND); } private static final int PATTERN_GAP_LENGTH_PX = 20; private static final PatternItem DOT = new Dot(); private static final PatternItem GAP = new Gap(PATTERN_GAP_LENGTH_PX); // Create a stroke pattern of a gap followed by a dot. private static final List<PatternItem> PATTERN_POLYLINE_DOTTED = Arrays.asList(GAP, DOT); /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ @Override public void onPolylineClick(Polyline polyline) { // Flip from solid stroke to dotted stroke pattern. if ((polyline.getPattern() == null) || (!polyline.getPattern().contains(DOT))) { polyline.setPattern(PATTERN_POLYLINE_DOTTED); } else { // The default pattern is a solid stroke. polyline.setPattern(null); } Toast.makeText(this, "Route type " + polyline.getTag().toString(), Toast.LENGTH_SHORT).show(); } /** * Listens for clicks on a polygon. * @param polygon The polygon object that the user has clicked. */ @Override public void onPolygonClick(Polygon polygon) { // Flip the values of the red, green, and blue components of the polygon's color. int color = polygon.getStrokeColor() ^ 0x00ffffff; polygon.setStrokeColor(color); color = polygon.getFillColor() ^ 0x00ffffff; polygon.setFillColor(color); Toast.makeText(this, "Area type " + polygon.getTag().toString(), Toast.LENGTH_SHORT).show(); } private static final int COLOR_WHITE_ARGB = 0xffffffff; private static final int COLOR_DARK_GREEN_ARGB = 0xff388E3C; private static final int COLOR_LIGHT_GREEN_ARGB = 0xff81C784; private static final int COLOR_DARK_ORANGE_ARGB = 0xffF57F17; private static final int COLOR_LIGHT_ORANGE_ARGB = 0xffF9A825; private static final int POLYGON_STROKE_WIDTH_PX = 8; private static final int PATTERN_DASH_LENGTH_PX = 20; private static final PatternItem DASH = new Dash(PATTERN_DASH_LENGTH_PX); // Create a stroke pattern of a gap followed by a dash. private static final List<PatternItem> PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH); // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private static final List<PatternItem> PATTERN_POLYGON_BETA = Arrays.asList(DOT, GAP, DASH, GAP); /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private void stylePolygon(Polygon polygon) { String type = ""; // Get the data object stored with the polygon. if (polygon.getTag() != null) { type = polygon.getTag().toString(); } List<PatternItem> pattern = null; int strokeColor = COLOR_BLACK_ARGB; int fillColor = COLOR_WHITE_ARGB; switch (type) { // If no type is given, allow the API to use the default. case "alpha": // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA; strokeColor = COLOR_DARK_GREEN_ARGB; fillColor = COLOR_LIGHT_GREEN_ARGB; break; case "beta": // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA; strokeColor = COLOR_DARK_ORANGE_ARGB; fillColor = COLOR_LIGHT_ORANGE_ARGB; break; } polygon.setStrokePattern(pattern); polygon.setStrokeWidth(POLYGON_STROKE_WIDTH_PX); polygon.setStrokeColor(strokeColor); polygon.setFillColor(fillColor); } }
Xem phiên bản Kotlin của hoạt động:
// 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.polygons import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.GoogleMap.OnPolygonClickListener import com.google.android.gms.maps.GoogleMap.OnPolylineClickListener import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.BitmapDescriptorFactory import com.google.android.gms.maps.model.CustomCap import com.google.android.gms.maps.model.Dash import com.google.android.gms.maps.model.Dot import com.google.android.gms.maps.model.Gap import com.google.android.gms.maps.model.JointType import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.PatternItem import com.google.android.gms.maps.model.Polygon import com.google.android.gms.maps.model.PolygonOptions import com.google.android.gms.maps.model.Polyline import com.google.android.gms.maps.model.PolylineOptions import com.google.android.gms.maps.model.RoundCap /** * An activity that displays a Google map with polylines to represent paths or routes, * and polygons to represent areas. */ class PolyActivity : AppCompatActivity(), OnMapReadyCallback, OnPolylineClickListener, OnPolygonClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ override fun onMapReady(googleMap: GoogleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.tag = "A" // Style the polyline. stylePolyline(polyline1) val polyline2 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-29.501, 119.700), LatLng(-27.456, 119.672), LatLng(-25.971, 124.187), LatLng(-28.081, 126.555), LatLng(-28.848, 124.229), LatLng(-28.215, 123.938))) polyline2.tag = "B" stylePolyline(polyline2) // Add polygons to indicate areas on the map. val polygon1 = googleMap.addPolygon(PolygonOptions() .clickable(true) .add( LatLng(-27.457, 153.040), LatLng(-33.852, 151.211), LatLng(-37.813, 144.962), LatLng(-34.928, 138.599))) // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.tag = "alpha" // Style the polygon. stylePolygon(polygon1) val polygon2 = googleMap.addPolygon(PolygonOptions() .clickable(true) .add( LatLng(-31.673, 128.892), LatLng(-31.952, 115.857), LatLng(-17.785, 122.258), LatLng(-12.4258, 130.7932))) polygon2.tag = "beta" stylePolygon(polygon2) // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-23.684, 133.903), 4f)) // Set listeners for click events. googleMap.setOnPolylineClickListener(this) googleMap.setOnPolygonClickListener(this) } private val COLOR_BLACK_ARGB = -0x1000000 private val POLYLINE_STROKE_WIDTH_PX = 12 /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private fun stylePolyline(polyline: Polyline) { // Get the data object stored with the polyline. val type = polyline.tag?.toString() ?: "" when (type) { "A" -> { // Use a custom bitmap as the cap at the start of the line. polyline.startCap = CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10f) } "B" -> { // Use a round cap at the start of the line. polyline.startCap = RoundCap() } } polyline.endCap = RoundCap() polyline.width = POLYLINE_STROKE_WIDTH_PX.toFloat() polyline.color = COLOR_BLACK_ARGB polyline.jointType = JointType.ROUND } private val PATTERN_GAP_LENGTH_PX = 20 private val DOT: PatternItem = Dot() private val GAP: PatternItem = Gap(PATTERN_GAP_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dot. private val PATTERN_POLYLINE_DOTTED = listOf(GAP, DOT) /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ override fun onPolylineClick(polyline: Polyline) { // Flip from solid stroke to dotted stroke pattern. if (polyline.pattern == null || !polyline.pattern!!.contains(DOT)) { polyline.pattern = PATTERN_POLYLINE_DOTTED } else { // The default pattern is a solid stroke. polyline.pattern = null } Toast.makeText(this, "Route type " + polyline.tag.toString(), Toast.LENGTH_SHORT).show() } /** * Listens for clicks on a polygon. * @param polygon The polygon object that the user has clicked. */ override fun onPolygonClick(polygon: Polygon) { // Flip the values of the red, green, and blue components of the polygon's color. var color = polygon.strokeColor xor 0x00ffffff polygon.strokeColor = color color = polygon.fillColor xor 0x00ffffff polygon.fillColor = color Toast.makeText(this, "Area type ${polygon.tag?.toString()}", Toast.LENGTH_SHORT).show() } private val COLOR_WHITE_ARGB = -0x1 private val COLOR_DARK_GREEN_ARGB = -0xc771c4 private val COLOR_LIGHT_GREEN_ARGB = -0x7e387c private val COLOR_DARK_ORANGE_ARGB = -0xa80e9 private val COLOR_LIGHT_ORANGE_ARGB = -0x657db private val POLYGON_STROKE_WIDTH_PX = 8 private val PATTERN_DASH_LENGTH_PX = 20 private val DASH: PatternItem = Dash(PATTERN_DASH_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dash. private val PATTERN_POLYGON_ALPHA = listOf(GAP, DASH) // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private val PATTERN_POLYGON_BETA = listOf(DOT, GAP, DASH, GAP) /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private fun stylePolygon(polygon: Polygon) { // Get the data object stored with the polygon. val type = polygon.tag?.toString() ?: "" var pattern: List<PatternItem>? = null var strokeColor = COLOR_BLACK_ARGB var fillColor = COLOR_WHITE_ARGB when (type) { "alpha" -> { // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA strokeColor = COLOR_DARK_GREEN_ARGB fillColor = COLOR_LIGHT_GREEN_ARGB } "beta" -> { // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA strokeColor = COLOR_DARK_ORANGE_ARGB fillColor = COLOR_LIGHT_ORANGE_ARGB } } polygon.strokePattern = pattern polygon.strokeWidth = POLYGON_STROKE_WIDTH_PX.toFloat() polygon.strokeColor = strokeColor polygon.fillColor = fillColor } }
Thiết lập dự án phát triển
Làm theo các bước sau để tạo dự án hướng dẫn trong Android Studio.
- Tải và cài đặt Android Studio.
- Thêm gói Dịch vụ Google Play vào Android Studio.
- Sao chép hoặc tải kho lưu trữ Mẫu API phiên bản 2 của Google Maps cho Android nếu bạn không làm như vậy khi bắt đầu đọc hướng dẫn này.
Nhập dự án hướng dẫn:
- Trong Android Studio, chọn File > (Tệp >) Mới > Nhập dự án.
- Chuyển đến vị trí bạn đã lưu Mẫu API Android phiên bản 2 của Google Maps sau khi tải xuống.
- Tìm dự án Đa giác tại vị trí này:
PATH-TO-SAVED-REPO/android-samples/tutorials/java/Polygons
(Java) hoặc
PATH-TO-SAVED-REPO/android-samples/tutorials/kotlin/Polygons
(Kotlin) - Chọn thư mục dự án, rồi nhấp vào Open (Mở). Android Studio hiện đã có bản dựng dự án của bạn bằng công cụ xây dựng Gradle.
Bật các API cần thiết và nhận khoá API
Để hoàn tất hướng dẫn này, bạn cần có một dự án trên Google Cloud có đầy đủ thông tin cần thiết Đã bật API và khoá API được phép sử dụng SDK bản đồ dành cho Android. Để biết thêm thông tin, hãy xem:
Thêm khoá API vào ứng dụng của bạn
- Mở tệp
local.properties
của dự án. Thêm chuỗi sau rồi thay thế
YOUR_API_KEY
bằng giá trị của khoá API của bạn:MAPS_API_KEY=YOUR_API_KEY
Khi bạn tạo ứng dụng, Trình bổ trợ Secrets Gradle cho Android sẽ sao chép khoá API và cung cấp khoá đó dưới dạng biến bản dựng trong Tệp kê khai Android, như giải thích bên dưới.
Tạo và chạy ứng dụng
Cách tạo và chạy ứng dụng:
Kết nối thiết bị Android với máy tính. Làm theo hướng dẫn bật tuỳ chọn cho nhà phát triển trên thiết bị Android thiết bị và định cấu hình hệ thống của bạn để phát hiện thiết bị.
Ngoài ra, bạn có thể sử dụng Trình quản lý thiết bị Android ảo (AVD) để định cấu hình một thiết bị ảo. Khi chọn một trình mô phỏng, hãy nhớ chọn một hình ảnh bao gồm các API của Google. Để biết thêm thông tin, hãy xem Thiết lập dự án Android Studio .
Trong Android Studio, hãy nhấp vào tuỳ chọn trình đơn Run (Chạy) (hoặc biểu tượng nút phát). Chọn một thiết bị khi được nhắc.
Android Studio gọi Gradle để tạo ứng dụng, sau đó chạy ứng dụng trên trên thiết bị hoặc trên trình mô phỏng.
Bạn sẽ thấy một bản đồ với hai đa giác phủ lên trên cùng của nước Úc, tương tự như hình ảnh trên trang này.
Gỡ rối:
- Nếu bạn không thấy bản đồ, hãy kiểm tra xem bạn đã lấy được khoá API và thêm khoá đó vào ứng dụng, như đã mô tả ở trên. Kiểm tra nhật ký trong Android Trình theo dõi Android của Studio để phát hiện các thông báo lỗi về khoá API.
- Sử dụng Công cụ gỡ lỗi của Android Studio để xem nhật ký và gỡ lỗi ứng dụng.
Tìm hiểu mã nguồn
Phần này của hướng dẫn giải thích các phần quan trọng nhất của ứng dụng Polygons, giúp bạn biết cách tạo một .
Kiểm tra tệp kê khai Android của bạn
Hãy lưu ý những phần tử sau trong tệp AndroidManifest.xml
của ứng dụng:
Thêm một phần tử
meta-data
để nhúng phiên bản của Dịch vụ Google Play ứng dụng được biên dịch.<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Thêm một phần tử
meta-data
để chỉ định khoá API của bạn. Mẫu đi kèm hướng dẫn này sẽ ánh xạ giá trị của khoá API với một biến bản dựng phù hợp tên của khoá mà bạn đã xác định trước đó,MAPS_API_KEY
. Khi bạn tạo ứng dụng, Trình bổ trợ Gradle cho Android sẽ cung cấp các khoá trong tệplocal.properties
của bạn dưới dạng bản dựng tệp kê khai biến.<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
Trong tệp
build.gradle
, dòng sau chuyển khoá API của bạn đến Tệp kê khai Android.id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Dưới đây là một ví dụ đầy đủ về một tệp kê khai:
<?xml version="1.0" encoding="utf-8"?> <!-- 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> <!-- The API key for Google Maps-based APIs. --> <meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" /> <activity android:name="com.example.polygons.PolyActivity" android:exported="true" android:label="@string/title_activity_maps"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Thêm bản đồ
Hiển thị bản đồ, sử dụng SDK Maps dành cho Android.
Thêm một phần tử
<fragment>
vào tệp bố cục của hoạt động,activity_maps.xml
Phần tử này xác định mộtSupportMapFragment
đóng vai trò là vùng chứa cho bản đồ và cấp quyền truy cập vào đối tượngGoogleMap
. Hướng dẫn sử dụng phiên bản thư viện hỗ trợ Android của mảnh bản đồ để đảm bảo khả năng tương thích ngược với các phiên bản trước đó của khung Android.<!-- 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. --> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.polygons.PolyActivity" />
Trong phương thức
onCreate()
của hoạt động, hãy đặt bố cục làm khung hiển thị nội dung. Xử lý mảnh bản đồ bằng cách gọiFragmentManager.findFragmentById()
. Sau đó sử dụnggetMapAsync()
để đăng ký lệnh gọi lại bản đồ:Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); }
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) }
Triển khai giao diện
OnMapReadyCallback
và ghi đè phương thứconMapReady()
. API gọi lệnh này gọi lại khi có đối tượngGoogleMap
để bạn có thể thêm vào bản đồ và tuỳ chỉnh thêm cho ứng dụng của mình:Java
public class PolyActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnPolylineClickListener, GoogleMap.OnPolygonClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ @Override public void onMapReady(GoogleMap googleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.684, 133.903), 4)); // Set listeners for click events. googleMap.setOnPolylineClickListener(this); googleMap.setOnPolygonClickListener(this); }
Kotlin
class PolyActivity : AppCompatActivity(), OnMapReadyCallback, OnPolylineClickListener, OnPolygonClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ override fun onMapReady(googleMap: GoogleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-23.684, 133.903), 4f)) // Set listeners for click events. googleMap.setOnPolylineClickListener(this) googleMap.setOnPolygonClickListener(this) }
Thêm hình nhiều đường để vẽ một đường trên bản đồ
Polyline
là một chuỗi các đoạn thẳng được kết nối. Hình nhiều đường là
hữu ích để thể hiện các tuyến đường, lối đi hoặc các mối kết nối khác giữa các vị trí trên
bản đồ.
Tạo một đối tượng
PolylineOptions
rồi thêm điểm vào đối tượng đó. Mỗi điểm đại diện cho một vị trí trên bản đồ, mà bạn xác định bằng một Đối tượngLatLng
chứa các giá trị vĩ độ và kinh độ. Chiến lược phát hành đĩa đơn mã mẫu bên dưới sẽ tạo một hình nhiều đường có 6 điểm.Gọi
GoogleMap.addPolyline()
để thêm hình nhiều đường vào bản đồ.Java
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309)));
Kotlin
val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309)))
Đặt tuỳ chọn clickable
của hình nhiều đường thành true
nếu bạn muốn xử lý lượt nhấp
các sự kiện trên hình nhiều đường. Chúng ta sẽ tìm hiểu thêm về cách xử lý sự kiện ở phần sau
của chúng tôi.
Lưu trữ dữ liệu tuỳ ý bằng hình nhiều đường
Bạn có thể lưu trữ đối tượng dữ liệu tuỳ ý bằng hình nhiều đường và các đối tượng hình học khác.
Gọi
Polyline.setTag()
để lưu trữ đối tượng dữ liệu bằng hình nhiều đường. Đoạn mã dưới đây xác định một thẻ tuỳ ý (A
) cho biết loại hình nhiều đường.Java
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.setTag("A");
Kotlin
val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Store a data object with the polyline, used here to indicate an arbitrary type. polyline1.tag = "A
Truy xuất dữ liệu bằng cách sử dụng
Polyline.getTag()
dưới dạng phần tiếp theo sẽ trình bày.
Thêm kiểu tuỳ chỉnh vào hình nhiều đường
Bạn có thể chỉ định các thuộc tính định kiểu khác nhau trong
Đối tượng PolylineOptions
. Các lựa chọn tạo kiểu bao gồm cả nét vẽ
màu, độ rộng nét vẽ, mẫu nét vẽ, loại khớp, chữ viết hoa đầu và cuối. Nếu bạn
không chỉ định một thuộc tính cụ thể, API sẽ sử dụng giá trị mặc định cho thuộc tính đó
thuộc tính này.
Mã sau đây áp dụng một hình tròn ở cuối dòng, và một giới hạn bắt đầu tuỳ thuộc vào loại hình nhiều đường, trong đó loại là giá trị tuỳ ý được lưu trữ trong đối tượng dữ liệu cho hình nhiều đường. Mẫu này cũng chỉ định độ rộng nét, màu nét và loại nối:
Java
private static final int COLOR_BLACK_ARGB = 0xff000000; private static final int POLYLINE_STROKE_WIDTH_PX = 12; /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private void stylePolyline(Polyline polyline) { String type = ""; // Get the data object stored with the polyline. if (polyline.getTag() != null) { type = polyline.getTag().toString(); } switch (type) { // If no type is given, allow the API to use the default. case "A": // Use a custom bitmap as the cap at the start of the line. polyline.setStartCap( new CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10)); break; case "B": // Use a round cap at the start of the line. polyline.setStartCap(new RoundCap()); break; } polyline.setEndCap(new RoundCap()); polyline.setWidth(POLYLINE_STROKE_WIDTH_PX); polyline.setColor(COLOR_BLACK_ARGB); polyline.setJointType(JointType.ROUND); }
Kotlin
private val COLOR_BLACK_ARGB = -0x1000000 private val POLYLINE_STROKE_WIDTH_PX = 12 /** * Styles the polyline, based on type. * @param polyline The polyline object that needs styling. */ private fun stylePolyline(polyline: Polyline) { // Get the data object stored with the polyline. val type = polyline.tag?.toString() ?: "" when (type) { "A" -> { // Use a custom bitmap as the cap at the start of the line. polyline.startCap = CustomCap( BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10f) } "B" -> { // Use a round cap at the start of the line. polyline.startCap = RoundCap() } } polyline.endCap = RoundCap() polyline.width = POLYLINE_STROKE_WIDTH_PX.toFloat() polyline.color = COLOR_BLACK_ARGB polyline.jointType = JointType.ROUND }
Đoạn mã ở trên chỉ định một bitmap tùy chỉnh cho giới hạn bắt đầu của loại A hình nhiều đường và chỉ định chiều rộng của nét chữ tham chiếu là 10 pixel. API mở rộng bitmap dựa trên chiều rộng của nét vẽ tham chiếu. Khi chỉ định tham chiếu chiều rộng nét, cung cấp chiều rộng mà bạn đã sử dụng khi thiết kế hình ảnh bitmap, ở kích thước ban đầu của hình ảnh. Gợi ý: Mở hình ảnh bitmap ở mức thu phóng 100% trong trình chỉnh sửa hình ảnh và vẽ đồ thị độ rộng mong muốn của nét vẽ tương ứng với hình ảnh.
Đọc thêm về giới hạn dòng và các tùy chọn khác cho tuỳ chỉnh hình dạng.
Xử lý sự kiện nhấp chuột trên hình nhiều đường
Làm cho hình nhiều đường có thể nhấp được bằng cách gọi
Polyline.setClickable()
. (Theo mặc định, hình nhiều đường không thể nhấp vào và ứng dụng của bạn sẽ không nhận được thông báo khi người dùng nhấn vào một hình nhiều đường.)Triển khai giao diện
OnPolylineClickListener
và gọiGoogleMap.setOnPolylineClickListener()
để thiết lập trình nghe trên bản đồ:Java
public class PolyActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnPolylineClickListener, GoogleMap.OnPolygonClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps); // Get the SupportMapFragment and request notification when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ @Override public void onMapReady(GoogleMap googleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. Polyline polyline1 = googleMap.addPolyline(new PolylineOptions() .clickable(true) .add( new LatLng(-35.016, 143.321), new LatLng(-34.747, 145.592), new LatLng(-34.364, 147.891), new LatLng(-33.501, 150.217), new LatLng(-32.306, 149.248), new LatLng(-32.491, 147.309))); // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.684, 133.903), 4)); // Set listeners for click events. googleMap.setOnPolylineClickListener(this); googleMap.setOnPolygonClickListener(this); }
Kotlin
class PolyActivity : AppCompatActivity(), OnMapReadyCallback, OnPolylineClickListener, OnPolygonClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps) // Get the SupportMapFragment and request notification when the map is ready to be used. val mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment? mapFragment?.getMapAsync(this) } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready to be used. * This is where we can add markers or lines, add listeners or move the camera. * In this tutorial, we add polylines and polygons to represent routes and areas on the map. */ override fun onMapReady(googleMap: GoogleMap) { // Add polylines to the map. // Polylines are useful to show a route or some other connection between points. val polyline1 = googleMap.addPolyline(PolylineOptions() .clickable(true) .add( LatLng(-35.016, 143.321), LatLng(-34.747, 145.592), LatLng(-34.364, 147.891), LatLng(-33.501, 150.217), LatLng(-32.306, 149.248), LatLng(-32.491, 147.309))) // Position the map's camera near Alice Springs in the center of Australia, // and set the zoom factor so most of Australia shows on the screen. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(-23.684, 133.903), 4f)) // Set listeners for click events. googleMap.setOnPolylineClickListener(this) googleMap.setOnPolygonClickListener(this) }
Ghi đè phương thức gọi lại
onPolylineClick()
. Chiến lược phát hành đĩa đơn ví dụ sau đây thay thế kiểu nét vẽ của đường thẳng giữa nét liền và chấm, mỗi khi người dùng nhấp vào hình nhiều đường:Java
private static final int PATTERN_GAP_LENGTH_PX = 20; private static final PatternItem DOT = new Dot(); private static final PatternItem GAP = new Gap(PATTERN_GAP_LENGTH_PX); // Create a stroke pattern of a gap followed by a dot. private static final List<PatternItem> PATTERN_POLYLINE_DOTTED = Arrays.asList(GAP, DOT); /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ @Override public void onPolylineClick(Polyline polyline) { // Flip from solid stroke to dotted stroke pattern. if ((polyline.getPattern() == null) || (!polyline.getPattern().contains(DOT))) { polyline.setPattern(PATTERN_POLYLINE_DOTTED); } else { // The default pattern is a solid stroke. polyline.setPattern(null); } Toast.makeText(this, "Route type " + polyline.getTag().toString(), Toast.LENGTH_SHORT).show(); }
Kotlin
private val PATTERN_GAP_LENGTH_PX = 20 private val DOT: PatternItem = Dot() private val GAP: PatternItem = Gap(PATTERN_GAP_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dot. private val PATTERN_POLYLINE_DOTTED = listOf(GAP, DOT) /** * Listens for clicks on a polyline. * @param polyline The polyline object that the user has clicked. */ override fun onPolylineClick(polyline: Polyline) { // Flip from solid stroke to dotted stroke pattern. if (polyline.pattern == null || !polyline.pattern!!.contains(DOT)) { polyline.pattern = PATTERN_POLYLINE_DOTTED } else { // The default pattern is a solid stroke. polyline.pattern = null } Toast.makeText(this, "Route type " + polyline.tag.toString(), Toast.LENGTH_SHORT).show() }
Thêm đa giác để biểu thị các khu vực trên bản đồ
Polygon
là một hình dạng bao gồm một loạt các toạ độ trong một
trình tự theo thứ tự, tương tự như Polyline
. Điểm khác biệt là
đa giác xác định một khu vực khép kín có phần bên trong có thể lấp đầy, trong khi đó là một hình nhiều đường
là kết thúc mở.
Tạo một đối tượng
PolygonOptions
rồi thêm điểm vào đối tượng đó. Mỗi điểm đại diện cho một vị trí trên bản đồ, mà bạn xác định bằng một Đối tượngLatLng
chứa các giá trị vĩ độ và kinh độ. Chiến lược phát hành đĩa đơn mã mẫu bên dưới sẽ tạo một đa giác có 4 điểm.Làm cho đa giác có thể nhấp được bằng cách gọi
Polygon.setClickable()
. (Theo mặc định, đa giác không thể nhấp vào và ứng dụng của bạn sẽ không nhận được thông báo khi người dùng nhấn vào một đa giác.) Việc xử lý các sự kiện nhấp chuột đa giác tương tự như xử lý sự kiện trên hình nhiều đường, được mô tả trước đó trong hướng dẫn này.Gọi
GoogleMap.addPolygon()
để thêm đa giác vào bản đồ.Gọi
Polygon.setTag()
để lưu trữ đối tượng dữ liệu bằng đa giác. Đoạn mã dưới đây định nghĩa một loại tuỳ ý (alpha
) cho đa giác.Java
// Add polygons to indicate areas on the map. Polygon polygon1 = googleMap.addPolygon(new PolygonOptions() .clickable(true) .add( new LatLng(-27.457, 153.040), new LatLng(-33.852, 151.211), new LatLng(-37.813, 144.962), new LatLng(-34.928, 138.599))); // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.setTag("alpha");
Kotlin
// Add polygons to indicate areas on the map. val polygon1 = googleMap.addPolygon(PolygonOptions() .clickable(true) .add( LatLng(-27.457, 153.040), LatLng(-33.852, 151.211), LatLng(-37.813, 144.962), LatLng(-34.928, 138.599))) // Store a data object with the polygon, used here to indicate an arbitrary type. polygon1.tag = "alpha" // Style the polygon.
Thêm kiểu tuỳ chỉnh vào đa giác
Bạn có thể chỉ định một số thuộc tính định kiểu trong
Đối tượng PolygonOptions
. Các lựa chọn tạo kiểu bao gồm cả nét vẽ
màu, độ rộng nét, mẫu nét vẽ, loại nối nét và màu tô. Nếu bạn
không chỉ định một thuộc tính cụ thể, API sẽ sử dụng giá trị mặc định cho thuộc tính đó
thuộc tính này.
Mã sau đây áp dụng các màu và mẫu nét vẽ cụ thể tuỳ thuộc vào loại đa giác, trong đó loại là một thuộc tính tuỳ ý được lưu trữ trong dữ liệu đối tượng cho đa giác:
Java
private static final int COLOR_WHITE_ARGB = 0xffffffff; private static final int COLOR_DARK_GREEN_ARGB = 0xff388E3C; private static final int COLOR_LIGHT_GREEN_ARGB = 0xff81C784; private static final int COLOR_DARK_ORANGE_ARGB = 0xffF57F17; private static final int COLOR_LIGHT_ORANGE_ARGB = 0xffF9A825; private static final int POLYGON_STROKE_WIDTH_PX = 8; private static final int PATTERN_DASH_LENGTH_PX = 20; private static final PatternItem DASH = new Dash(PATTERN_DASH_LENGTH_PX); // Create a stroke pattern of a gap followed by a dash. private static final List<PatternItem> PATTERN_POLYGON_ALPHA = Arrays.asList(GAP, DASH); // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private static final List<PatternItem> PATTERN_POLYGON_BETA = Arrays.asList(DOT, GAP, DASH, GAP); /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private void stylePolygon(Polygon polygon) { String type = ""; // Get the data object stored with the polygon. if (polygon.getTag() != null) { type = polygon.getTag().toString(); } List<PatternItem> pattern = null; int strokeColor = COLOR_BLACK_ARGB; int fillColor = COLOR_WHITE_ARGB; switch (type) { // If no type is given, allow the API to use the default. case "alpha": // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA; strokeColor = COLOR_DARK_GREEN_ARGB; fillColor = COLOR_LIGHT_GREEN_ARGB; break; case "beta": // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA; strokeColor = COLOR_DARK_ORANGE_ARGB; fillColor = COLOR_LIGHT_ORANGE_ARGB; break; } polygon.setStrokePattern(pattern); polygon.setStrokeWidth(POLYGON_STROKE_WIDTH_PX); polygon.setStrokeColor(strokeColor); polygon.setFillColor(fillColor); }
Kotlin
private val COLOR_WHITE_ARGB = -0x1 private val COLOR_DARK_GREEN_ARGB = -0xc771c4 private val COLOR_LIGHT_GREEN_ARGB = -0x7e387c private val COLOR_DARK_ORANGE_ARGB = -0xa80e9 private val COLOR_LIGHT_ORANGE_ARGB = -0x657db private val POLYGON_STROKE_WIDTH_PX = 8 private val PATTERN_DASH_LENGTH_PX = 20 private val DASH: PatternItem = Dash(PATTERN_DASH_LENGTH_PX.toFloat()) // Create a stroke pattern of a gap followed by a dash. private val PATTERN_POLYGON_ALPHA = listOf(GAP, DASH) // Create a stroke pattern of a dot followed by a gap, a dash, and another gap. private val PATTERN_POLYGON_BETA = listOf(DOT, GAP, DASH, GAP) /** * Styles the polygon, based on type. * @param polygon The polygon object that needs styling. */ private fun stylePolygon(polygon: Polygon) { // Get the data object stored with the polygon. val type = polygon.tag?.toString() ?: "" var pattern: List<PatternItem>? = null var strokeColor = COLOR_BLACK_ARGB var fillColor = COLOR_WHITE_ARGB when (type) { "alpha" -> { // Apply a stroke pattern to render a dashed line, and define colors. pattern = PATTERN_POLYGON_ALPHA strokeColor = COLOR_DARK_GREEN_ARGB fillColor = COLOR_LIGHT_GREEN_ARGB } "beta" -> { // Apply a stroke pattern to render a line of dots and dashes, and define colors. pattern = PATTERN_POLYGON_BETA strokeColor = COLOR_DARK_ORANGE_ARGB fillColor = COLOR_LIGHT_ORANGE_ARGB } } polygon.strokePattern = pattern polygon.strokeWidth = POLYGON_STROKE_WIDTH_PX.toFloat() polygon.strokeColor = strokeColor polygon.fillColor = fillColor }
Đọc thêm về mẫu nét vẽ và các lựa chọn khác cho tuỳ chỉnh hình dạng.
Các bước tiếp theo
Tìm hiểu về đối tượng Vòng tròn. Vòng tròn tương tự như đa giác nhưng có các thuộc tính phản ánh hình dạng của hình tròn.