1. शुरू करने से पहले
यह कोडलैब आपको Android के लिए Maps SDK टूल को अपने ऐप्लिकेशन से इंटिग्रेट करने और मुख्य सुविधाओं का इस्तेमाल करने का तरीका बताता है. यह ऐप्लिकेशन सैन फ़्रांसिस्को, अमेरिका, अमेरिका में साइकल की दुकानों का मैप दिखाता है.
ज़रूरी बातें
- Kotlin और Android डेवलपमेंट की बुनियादी जानकारी
आप क्या कर पाएंगे!
- किसी Android ऐप्लिकेशन में Google Maps जोड़ने के लिए, Android के लिए Maps SDK चालू करें और उसका इस्तेमाल करें.
- मार्कर जोड़ें, कस्टमाइज़ करें, और क्लस्टर बनाएं.
- मैप पर पॉलीलाइन और पॉलीगॉन बनाएं.
- कैमरे की दिखावट को प्रोग्रामैटिक तौर पर कंट्रोल करें.
आपको इनकी ज़रूरत होगी
- Android के लिए Maps SDK टूल
- बिलिंग की सुविधा वाला Google खाता
- Android Studio 2020.3.1 या इसके बाद का वर्शन
- Android Studio में Google Play सेवाएं इंस्टॉल की गईं
- कोई Android डिवाइस या Android एम्युलेटर, जो Android 4.2.2 या इसके बाद वाले वर्शन पर आधारित Google API प्लैटफ़ॉर्म चलाता है. (इंस्टॉल करने के तरीके के बारे में जानने के लिए, Android एम्युलेटर पर ऐप्लिकेशन चलाएं देखें.)
2. सेट अप करें
नीचे दिए गए चालू करने के चरण के लिए , आपको Android के लिए Maps SDK टूल को चालू करना होगा.
Google Maps Platform सेट अप करना
अगर आपके पास पहले से Google Cloud Platform खाता नहीं है और बिलिंग की सुविधा चालू की गई है, तो कृपया बिलिंग खाता और प्रोजेक्ट बनाने के लिए, Google Maps Platform का इस्तेमाल शुरू करना गाइड देखें.
- Cloud Console में, प्रोजेक्ट ड्रॉप-डाउन मेन्यू पर क्लिक करें और वह प्रोजेक्ट चुनें जिसे आप इस कोडलैब के लिए इस्तेमाल करना चाहते हैं.
- Google Cloud Marketplace में, इस कोडलैब के लिए ज़रूरी Google Maps Platform API और SDK टूल चालू करें. ऐसा करने के लिए, इस वीडियो या इस दस्तावेज़ में दिया गया तरीका अपनाएं.
- Cloud Console के क्रेडेंशियल पेज में एपीआई कुंजी जनरेट करें. आप इस वीडियो या इस दस्तावेज़ में दिया गया तरीका अपना सकते हैं. Google Maps Platform पर सभी अनुरोधों के लिए एपीआई कुंजी ज़रूरी है.
3. तुरंत शुरू करना
इसे शुरू करने में आपकी मदद करने के लिए, यहां कुछ # कोड दिया गया है, ताकि इस कोडलैब के साथ आपको मदद मिल सके. आप जब चाहें, इस कार्यक्रम में हिस्सा ले सकते हैं. हालांकि, अगर आप इस समस्या को खुद हल करने के सभी तरीके जानना चाहते हैं, तो पढ़ते रहें.
- अगर आपने
git
इंस्टॉल किया हुआ है, तो रिपॉज़िटरी क्लोन करें.
git clone https://github.com/googlecodelabs/maps-platform-101-android.git
इसके अलावा, आप सोर्स कोड डाउनलोड करने के लिए इस बटन पर क्लिक कर सकते हैं.
- कोड मिलने के बाद, Android Studio में
starter
डायरेक्ट्री में मिलने वाला प्रोजेक्ट खोलें.
4. Google Maps जोड़ें
इस सेक्शन में, आपको Google Maps जोड़ना होगा, ताकि जब आप ऐप्लिकेशन लॉन्च करें, तो वह लोड हो जाए.
अपनी एपीआई कुंजी जोड़ें
आपने पहले जो एपीआई कुंजी बनाई थी वह ऐप्लिकेशन को दी जानी चाहिए, ताकि Android के लिए Maps SDK टूल, आपकी कुंजी को आपके ऐप्लिकेशन से जोड़ सके.
- इसे उपलब्ध कराने के लिए,
local.properties
नाम की फ़ाइल को अपने प्रोजेक्ट की रूट डायरेक्ट्री में खोलें (उसी लेवल पर जहांgradle.properties
औरsettings.gradle
हैं). - उस फ़ाइल में, उस नई कुंजी के बारे में
GOOGLE_MAPS_API_KEY
बताएं जिसे आपने एपीआई कुंजी के तौर पर बनाया है.
local.properties
GOOGLE_MAPS_API_KEY=YOUR_KEY_HERE
ध्यान दें कि local.properties
, GIF डेटा स्टोर करने की जगह में .gitignore
फ़ाइल की सूची में है. ऐसा इसलिए है, क्योंकि आपकी एपीआई कुंजी को संवेदनशील जानकारी माना जाता है. अगर हो सके, तो इसे सोर्स कंट्रोल में नहीं देखना चाहिए.
- इसके बाद, अपने एपीआई को बिना अनुमति के सार्वजनिक करें, ताकि वह आपके ऐप्लिकेशन में इस्तेमाल किया जा सके. अपने ऐप्लिकेशन में Android के लिए सीक्रेट Gradle प्लग इन
app/
फ़ाइल में मौजूदbuild.gradle
फ़ाइल शामिल करें.plugins
ब्लॉक में नीचे दी गई लाइन जोड़ें:
ऐप्लिकेशन-लेवल build.gradle
plugins {
// ...
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}
आपको अपने प्रोजेक्ट-लेवल की build.gradle
फ़ाइल में बदलाव करना होगा, ताकि नीचे दिए गए क्लासपाथ को शामिल किया जा सके:
प्रोजेक्ट-लेवल build.gradle
buildscript {
dependencies {
// ...
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:1.3.0"
}
}
यह प्लग इन, आपकी local.properties
फ़ाइल में तय किए गए बटन को Android मेनिफ़ेस्ट फ़ाइल में बिल्ड वैरिएबल के तौर पर और बिल्ड टाइम में Gradle से जनरेट की गई BuildConfig
क्लास के वैरिएबल के तौर पर उपलब्ध कराएगा. इस प्लग इन का इस्तेमाल करके, उन बॉयलरप्लेट कोड को हटा दिया जाता है जो local.properties
से प्रॉपर्टी पढ़ने के लिए ज़रूरी होते, ताकि यह आपके पूरे ऐप्लिकेशन में ऐक्सेस किया जा सके.
Google Maps में डिपेंडेंसी जोड़ना
- अब आपकी एपीआई कुंजी को ऐप्लिकेशन में ऐक्सेस किया जा सकता है. इसके बाद, अपने ऐप्लिकेशन की
build.gradle
फ़ाइल में Android डिपेंडेंसी के लिए Maps SDK टूल जोड़ें.
इस कोडलैब के साथ मिलने वाले स्टार्टर प्रोजेक्ट में, इस डिपेंडेंसी को आपके लिए पहले ही जोड़ा जा चुका है.
build.gradle
dependencies {
// Dependency to include Maps SDK for Android
implementation 'com.google.android.gms:play-services-maps:17.0.0'
}
- इसके बाद, आपने एपीआई कुंजी को पास करने के लिए
AndroidManifest.xml
में एक नयाmeta-data
टैग जोड़ा है. ऐसा करने के लिए,meta-data
और Android Studio में इस फ़ाइल को खोलें. इसके बाद,app/src/main
में मौजूद अपनीAndroidManifest.xml
फ़ाइल केapplication
ऑब्जेक्ट में इसmeta-data
टैग को जोड़ें.
AndroidManifest.xml
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${GOOGLE_MAPS_API_KEY}" />
- इसके बाद,
app/src/main/res/layout/
निर्देशिका मेंactivity_main.xml
नाम की एक नई लेआउट फ़ाइल बनाएं और इसे इस तरह तय करें:
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
class="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
इस लेआउट में FrameLayout
शामिल है, जिसमें एक SupportMapFragment
है. इस फ़्रैगमेंट में वह GoogleMaps
ऑब्जेक्ट शामिल है जिसका इस्तेमाल आप बाद के चरणों में करते हैं.
- आखिर में,
onCreate
तरीके को बदलने के लिए नीचे दिया गया कोड जोड़कर,app/src/main/java/com/google/codelabs/buildyourfirstmap
में मौजूदMainActivity
क्लास को अपडेट करें, ताकि आप अभी-अभी बनाए गए नए लेआउट से इसके कॉन्टेंट सेट कर सकें.
MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
- अब आगे बढ़ें और ऐप्लिकेशन चलाएं. अब आपको अपने डिवाइस की स्क्रीन पर मैप लोड दिखेगा.
5. क्लाउड-आधारित मैप स्टाइलिंग (ज़रूरी नहीं)
क्लाउड पर आधारित मैप स्टाइल का इस्तेमाल करके आप अपने मैप की शैली को पसंद के मुताबिक बना सकते हैं.
एक मैप आईडी बनाएं
अगर आपने अभी तक मैप शैली के साथ कोई मैप आईडी नहीं बनाया है, तो नीचे दिए गए चरणों को पूरा करने के लिए मैप आईडी गाइड देखें:
- एक मैप आईडी बनाएं.
- किसी मैप आईडी को किसी मैप शैली से जोड़ें.
अपने ऐप्लिकेशन में मैप आईडी जोड़ना
आपने जो मैप आईडी बनाया है उसका इस्तेमाल करने के लिए, activity_main.xml
फ़ाइल में बदलाव करें और SupportMapFragment
के map:mapId
एट्रिब्यूट में अपना मैप आईडी पास करें.
activity_main.xml
<fragment xmlns:map="http://schemas.android.com/apk/res-auto"
class="com.google.android.gms.maps.SupportMapFragment"
<!-- ... -->
map:mapId="YOUR_MAP_ID" />
जब आप इसे पूरा कर लें, तब आगे बढ़ें और अपनी चुनी हुई शैली में अपना मैप देखने के लिए ऐप्लिकेशन चलाएं!
6. मार्कर जोड़ें
इस टास्क में, आप मैप पर मार्कर जोड़ते हैं. ये मैप में आपकी पसंद की जगहों को हाइलाइट करते हैं. पहले, आप उन जगहों की सूची लाते हैं जो आपको स्टार्टर प्रोजेक्ट में दी गई हैं. इसके बाद, उन जगहों को मैप में जोड़ें. इस उदाहरण में, ये साइकल की दुकानें हैं.
Google मैप का रेफ़रंस पाना
सबसे पहले, आपको GoogleMap
ऑब्जेक्ट का रेफ़रंस लेना होगा, ताकि आप उसके तरीकों का इस्तेमाल कर सकें. ऐसा करने के लिए, setContentView()
पर कॉल करने के तुरंत बाद, MainActivity.onCreate()
तरीके में यह कोड जोड़ें:
MainActivity.onCreate()
val mapFragment = supportFragmentManager.findFragmentById(
R.id.map_fragment
) as? SupportMapFragment
mapFragment?.getMapAsync { googleMap ->
addMarkers(googleMap)
}
लागू करने से पहले, आपने SupportFragmentManager
ऑब्जेक्ट पर findFragmentById()
तरीका इस्तेमाल करके पिछले चरण में SupportMapFragment
को जोड़ा था. एक बार पहचान मिलने के बाद, getMapAsync()
कॉल को lambda से पास करके शुरू किया जाता है. यह Lambda है जहां GoogleMap
ऑब्जेक्ट को पास किया गया है. इस lambda में, addMarkers()
मेथड को कॉल किया जाता है, जिसके बारे में जल्द ही बताया गया है.
दी गई श्रेणी: Places रीडर
स्टार्टर प्रोजेक्ट में, PlacesReader
क्लास आपके लिए उपलब्ध है. यह क्लास 49 जगहों की सूची पढ़ती है जो places.json
नाम की JSON फ़ाइल में सेव हैं और उन्हें List<Place>
के तौर पर दिखाती हैं. ये जगहें खुद सैन फ़्रांसिस्को, कैलिफ़ोर्निया, अमेरिका के आस-पास मौजूद साइकल की दुकानों की सूची दिखाती हैं.
अगर आप इस क्लास को लागू करने के बारे में जानना चाहते हैं, तो इसे GitHub पर ऐक्सेस कर सकते हैं या Android Studio में PlacesReader
क्लास को खोल सकते हैं.
PlaceReader
package com.google.codelabs.buildyourfirstmap.place
import android.content.Context
import com.google.codelabs.buildyourfirstmap.R
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.io.InputStream
import java.io.InputStreamReader
/**
* Reads a list of place JSON objects from the file places.json
*/
class PlacesReader(private val context: Context) {
// GSON object responsible for converting from JSON to a Place object
private val gson = Gson()
// InputStream representing places.json
private val inputStream: InputStream
get() = context.resources.openRawResource(R.raw.places)
/**
* Reads the list of place JSON objects in the file places.json
* and returns a list of Place objects
*/
fun read(): List<Place> {
val itemType = object : TypeToken<List<PlaceResponse>>() {}.type
val reader = InputStreamReader(inputStream)
return gson.fromJson<List<PlaceResponse>>(reader, itemType).map {
it.toPlace()
}
}
जगहों की जानकारी लोड करें
साइकल की दुकानों की सूची लोड करने के लिए, MainActivity
नाम वाली प्रॉपर्टी जोड़ें, जिसका नाम places
है. इसे इस तरह परिभाषित करें:
MainActivity.जगहें
private val places: List<Place> by lazy {
PlacesReader(this).read()
}
यह कोड PlacesReader
पर read()
तरीके का इस्तेमाल करता है, जो List<Place>
दिखाता है. Place
में name
नाम की प्रॉपर्टी होती है, जगह का नाम होता है, और latLng
—ऐसे निर्देशांक होते हैं जहां जगह मौजूद होती है.
जगह
data class Place(
val name: String,
val latLng: LatLng,
val address: LatLng,
val rating: Float
)
मैप में मार्कर जोड़ें
अब जब जगहों की सूची स्टोरेज में लोड हो गई है, तो अगला चरण मैप पर इन जगहों को दिखाना है.
MainActivity
नाम की एक विधि बनाएं, जिसका नामaddMarkers()
हो और इसे इस तरह परिभाषित करें:
MainActivity.addmarkers()
/**
* Adds marker representations of the places list on the provided GoogleMap object
*/
private fun addMarkers(googleMap: GoogleMap) {
places.forEach { place ->
val marker = googleMap.addMarker(
MarkerOptions()
.title(place.name)
.position(place.latLng)
)
}
}
इस तरीके से places
की सूची में दोहराया जाता है. इसके बाद, दिए गए GoogleMap
ऑब्जेक्ट पर addMarker()
का तरीका शुरू किया जाता है. मार्कर को MarkerOptions
ऑब्जेक्ट को इंस्टैंशिएट करके बनाया जाता है, जिससे आप मार्कर को पसंद के मुताबिक बना सकते हैं. इस स्थिति में, मार्कर का शीर्षक और स्थिति दी जाती है, जो साइकल की दुकान के नाम और उसके निर्देशांकों को दिखाता है.
- आगे बढ़ें और ऐप्लिकेशन चलाएं और अभी-अभी जोड़े गए मार्कर देखने के लिए सैन फ़्रांसिस्को में जाएं!
7. मार्कर कस्टमाइज़ करें
मार्कर के लिए ऐसे कई कस्टमाइज़ेशन विकल्प उपलब्ध हैं जिन्हें आपने अभी-अभी जोड़ा है, ताकि उपयोगकर्ताओं को अलग दिखाई देने और उपयोगी जानकारी देने में उन्हें सहायता मिले. इस काम में, आप हर मार्कर की इमेज को पसंद के मुताबिक बना सकते हैं. साथ ही, मार्कर पर टैप करके मिलने वाली जानकारी विंडो को भी पसंद के मुताबिक बना सकते हैं.
जानकारी विंडो जोड़ना
डिफ़ॉल्ट रूप से, किसी मार्कर पर टैप करने पर जानकारी विंडो में शीर्षक और स्निपेट (अगर सेट है) दिखते हैं. आप इसे कस्टमाइज़ करें, ताकि इसमें जगह और #39; के पते और रेटिंग जैसी अन्य जानकारी दिख सके.
मार्कर_info_contents.xml बनाएं
सबसे पहले, marker_info_contents.xml
नाम की एक नई लेआउट फ़ाइल बनाएं.
- ऐसा करने के लिए, Android Studio के प्रोजेक्ट व्यू में
app/src/main/res/layout
फ़ोल्डर पर दायां क्लिक करें और नया > लेआउट रिसॉर्स फ़ाइल को चुनें.
- डायलॉग बॉक्स में, फ़ाइल नाम फ़ील्ड में
marker_info_contents
औरRoot element
फ़ील्ड मेंLinearLayout
टाइप करें. इसके बाद, ठीक है पर क्लिक करें.
इस लेआउट फ़ाइल को बाद में जानकारी विंडो में मौजूद कॉन्टेंट को दिखाने के लिए बढ़ाया जाता है.
- नीचे दिए गए कोड स्निपेट में कॉन्टेंट कॉपी करें, जो वर्टिकल
LinearLayout
व्यू ग्रुप में तीनTextViews
जोड़ता है और फ़ाइल का डिफ़ॉल्ट कोड ओवरराइट कर देता है.
mark_info_contents.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="8dp">
<TextView
android:id="@+id/text_view_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold"
tools:text="Title"/>
<TextView
android:id="@+id/text_view_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="16sp"
tools:text="123 Main Street"/>
<TextView
android:id="@+id/text_view_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="16sp"
tools:text="Rating: 3"/>
</LinearLayout>
InfoविंडोAdapter को लागू करना
कस्टम जानकारी विंडो के लिए लेआउट फ़ाइल बनाने के बाद, अगला चरण है GoogleMap.InfoविंडोAdapter इंटरफ़ेस लागू करना. इस इंटरफ़ेस में getInfoWindow()
और getInfoContents()
दो तरीके हैं. दोनों तरीकों में एक वैकल्पिक View
ऑब्जेक्ट मिलता है, जिसमें पहले का इस्तेमाल विंडो को पसंद के मुताबिक बनाने के लिए किया जाता है. वहीं, दूसरा ऑब्जेक्ट अपने कॉन्टेंट को पसंद के मुताबिक बना सकता है. अपने मामले में, आप दोनों को लागू करते हैं और getInfoWindow()
में शून्य दिखाते हुए getInfoContents()
के रिटर्न को पसंद के मुताबिक बनाते हैं, जो यह बताता है कि डिफ़ॉल्ट विंडो का इस्तेमाल किया जाना चाहिए.
- Android Studio में प्रोजेक्ट व्यू के
app/src/main/java/com/google/codelabs/buildyourfirstmap
फ़ोल्डर पर दायां क्लिक करें. इसके बाद,MarkerInfoWindowAdapter
वाले पैकेज में,MarkerInfoWindowAdapter
के नाम से एक नई Kotlin फ़ाइल बनाएं. इसके बाद, नया > Kotlin फ़ाइल/क्लास चुनें.
- डायलॉग बॉक्स में,
MarkerInfoWindowAdapter
टाइप करें और फ़ाइल को हाइलाइट करके रखें.
- फ़ाइल बनाने के बाद, नीचे दिए गए कोड स्निपेट में मौजूद कॉन्टेंट को अपनी नई फ़ाइल में कॉपी करें.
मार्कर जानकारी विंडो अडैप्टर
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.Marker
import com.google.codelabs.buildyourfirstmap.place.Place
class MarkerInfoWindowAdapter(
private val context: Context
) : GoogleMap.InfoWindowAdapter {
override fun getInfoContents(marker: Marker?): View? {
// 1. Get tag
val place = marker?.tag as? Place ?: return null
// 2. Inflate view and set title, address, and rating
val view = LayoutInflater.from(context).inflate(
R.layout.marker_info_contents, null
)
view.findViewById<TextView>(
R.id.text_view_title
).text = place.name
view.findViewById<TextView>(
R.id.text_view_address
).text = place.address
view.findViewById<TextView>(
R.id.text_view_rating
).text = "Rating: %.2f".format(place.rating)
return view
}
override fun getInfoWindow(marker: Marker?): View? {
// Return null to indicate that the
// default window (white bubble) should be used
return null
}
}
getInfoContents()
तरीके के कॉन्टेंट में, दिए गए मार्कर को Place
टाइप में कास्ट किया जाता है और कास्ट करना मुमकिन नहीं है, तो यह तरीका शून्य (##39) सेट करता है और आप Marker
पर टैग प्रॉपर्टी सेट नहीं करते. हालांकि, अगले चरण में आप ऐसा करते हैं.
इसके बाद, marker_info_contents.xml
लेआउट को इनफ़्लेट किया जाता है. इसके बाद, TextViews
में Place
टैग पर टेक्स्ट सेट किया जाता है.
MainActivity को अपडेट करें
अपने अब तक बनाए गए सभी कॉम्पोनेंट को चिपकाने के लिए, आपको MainActivity
क्लास में दो लाइनें जोड़नी होंगी.
सबसे पहले, getMapAsync
विधि कॉल के अंदर, कस्टम InfoWindowAdapter
, MarkerInfoWindowAdapter
को पास करने के लिए, GoogleMap
ऑब्जेक्ट पर setInfoWindowAdapter()
विधि शुरू करें और MarkerInfoWindowAdapter
का एक नया इंस्टेंस बनाएं.
getMapAsync()
lambda मेंaddMarkers()
वाले तरीके से कॉल करने के बाद, नीचे दिया गया कोड जोड़कर ऐसा करें.
MainActivity.onCreate()
// Set custom info window adapter
googleMap.setInfoWindowAdapter(MarkerInfoWindowAdapter(this))
आखिर में, आपको हर जगह को मैप पर जोड़े गए हर मार्कर पर टैग प्रॉपर्टी के तौर पर सेट करना होगा.
- ऐसा करने के लिए,
addMarkers()
फ़ंक्शन में,places.forEach{}
कॉल में यह बदलाव करें:
MainActivity.addmarkers()
places.forEach { place ->
val marker = googleMap.addMarker(
MarkerOptions()
.title(place.name)
.position(place.latLng)
.icon(bicycleIcon)
)
// Set place as the tag on the marker object so it can be referenced within
// MarkerInfoWindowAdapter
marker.tag = place
}
पसंद के मुताबिक मार्कर इमेज जोड़ें
मार्कर इमेज को पसंद के मुताबिक बनाना, आपके मैप पर मार्कर के ज़रिए दिखाई जाने वाली जगह के प्रकार को बताने का एक मज़ेदार तरीका है. इस चरण में, मैप पर मौजूद हर दुकान को दिखाने के लिए, आप डिफ़ॉल्ट लाल मार्कर के बजाय साइकल को दिखाएंगे. स्टार्टर प्रोजेक्ट में, app/src/res/drawable
में साइकिल आइकॉन ic_directions_bike_black_24dp.xml
शामिल है. आप इसका इस्तेमाल करते हैं.
मार्कर पर कस्टम बिट मैप सेट करें
वेक्टर को इकट्ठा करने वाले साइकल के आइकॉन, आपके मैप पर अगला कदम होगा कि हर मार्कर और #39; आइकॉन के रूप में ड्रॉ किया जा सकता है. MarkerOptions
में icon
एक तरीका है. इसे पूरा करने के लिए, आपको BitmapDescriptor
का इस्तेमाल करना होता है.
सबसे पहले, आपको उस वेक्टर ड्रॉ करने की सुविधा को बदलना होगा जिसे आपने अभी-अभी BitmapDescriptor
में जोड़ा है. स्टार्टर प्रोजेक्ट में BitMapHelper
नाम की एक फ़ाइल का vectorToBitmap()
शामिल है, जो हेल्पर फ़ंक्शन के तौर पर काम करता है.
बिट मैपहेल्पर
package com.google.codelabs.buildyourfirstmap
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.util.Log
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.DrawableCompat
import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory
object BitmapHelper {
/**
* Demonstrates converting a [Drawable] to a [BitmapDescriptor],
* for use as a marker icon. Taken from ApiDemos on GitHub:
* https://github.com/googlemaps/android-samples/blob/main/ApiDemos/kotlin/app/src/main/java/com/example/kotlindemos/MarkerDemoActivity.kt
*/
fun vectorToBitmap(
context: Context,
@DrawableRes id: Int,
@ColorInt color: Int
): BitmapDescriptor {
val vectorDrawable = ResourcesCompat.getDrawable(context.resources, id, null)
if (vectorDrawable == null) {
Log.e("BitmapHelper", "Resource not found")
return BitmapDescriptorFactory.defaultMarker()
}
val bitmap = Bitmap.createBitmap(
vectorDrawable.intrinsicWidth,
vectorDrawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
vectorDrawable.setBounds(0, 0, canvas.width, canvas.height)
DrawableCompat.setTint(vectorDrawable, color)
vectorDrawable.draw(canvas)
return BitmapDescriptorFactory.fromBitmap(bitmap)
}
}
इस तरीके में Context
, एक ड्रॉ करने लायक रिसॉर्स आईडी, और एक कलर इंटिजर होता है. साथ ही, यह BitmapDescriptor
का प्रतिनिधित्व करता है.
हेल्पर वाले तरीके का इस्तेमाल करके, bicycleIcon
नाम की नई प्रॉपर्टी का एलान करें और यह जानकारी दें: MainActivity.bicycleIcon
private val bicycleIcon: BitmapDescriptor by lazy {
val color = ContextCompat.getColor(this, R.color.colorPrimary)
BitmapHelper.vectorToBitmap(this, R.drawable.ic_directions_bike_black_24dp, color)
}
यह प्रॉपर्टी आपके ऐप्लिकेशन में पहले से तय रंग colorPrimary
का इस्तेमाल करती है. इसका इस्तेमाल, साइकल के आइकॉन को रंगने और इसे BitmapDescriptor
के तौर पर दिखाने के लिए किया जाता है.
- इस प्रॉपर्टी का इस्तेमाल करके, अपने आइकॉन को पसंद के मुताबिक बनाने के लिए,
addMarkers()
वाले तरीके मेंMarkerOptions
काicon
तरीका शुरू करें. ऐसा करने पर, मार्कर प्रॉपर्टी कुछ इस तरह दिखेगी:
MainActivity.addmarkers()
val marker = googleMap.addMarker(
MarkerOptions()
.title(place.name)
.position(place.latLng)
.icon(bicycleIcon)
)
- अपडेट किए गए मार्कर देखने के लिए ऐप्लिकेशन चलाएं!
8. क्लस्टर मार्कर
मैप में आप जितनी दूर ज़ूम इन करते हैं, इसके आधार पर आपने देखा होगा कि आपने जो मार्कर जोड़े हैं वे ओवरलैप कर रहे हैं. ओवरलैप करने वाले मार्कर के साथ इंटरैक्ट करना और बहुत ज़्यादा शोर बनाना बहुत कठिन होता है, जिससे आपके ऐप्लिकेशन की उपयोगिता पर असर पड़ता है.
इसके लिए उपयोगकर्ता अनुभव को बेहतर बनाने के लिए, जब भी आपके पास कोई बड़ा डेटासेट इकट्ठा होता है, तब मार्कर मार्कर को लागू करने का यह सबसे सही तरीका है. क्लस्टरिंग के साथ, जब आप मैप को ज़ूम इन और ज़ूम आउट करते हैं, तो आस-पास के मार्कर इस तरह इकट्ठा किए जाते हैं:
इसे लागू करने के लिए, आपको Android Utility लाइब्रेरी के लिए Maps SDK टूल की मदद लेनी होगी.
Android Utility लाइब्रेरी के लिए Maps SDK टूल
Android Utility लाइब्रेरी के लिए Maps SDK टूल, Android के लिए Maps SDK टूल की सुविधाओं को बेहतर बनाने के तरीके के तौर पर बनाया गया है. इसमें मार्कर क्लस्टरिंग, हीटमैप, KML और GeoJson सहायता, पॉलीलाइन एन्कोडिंग, और डिकोडिंग जैसी बेहतर सुविधाएं हैं. साथ ही, गोल आकार वाली ज्यामिति के कुछ मददगार फ़ंक्शन भी हैं.
अपनी build.gradle को अपडेट करना
उपयोगिता लाइब्रेरी को Android के लिए मैप SDK टूल से अलग से पैकेज किया गया है, इसलिए आपको अपनी build.gradle
फ़ाइल में एक और डिपेंडेंसी जोड़नी होगी.
- आगे बढ़ें और अपनी
app/build.gradle
फ़ाइल केdependencies
सेक्शन को अपडेट करें.
build.gradle
implementation 'com.google.maps.android:android-maps-utils:1.1.0'
- इस लाइन को जोड़ने पर, आपको नई डिपेंडेंसी लाने के लिए प्रोजेक्ट सिंक करना होगा.
क्लस्टर लागू करना
अपने ऐप्लिकेशन पर क्लस्टर लागू करने के लिए, इन तीन चरणों का पालन करें:
ClusterItem
इंटरफ़ेस लागू करें.DefaultClusterRenderer
क्लास को सब-क्लास करें.ClusterManager
बनाएं और आइटम जोड़ें.
ClusterItem इंटरफ़ेस लागू करना
मैप पर क्लस्टर करने लायक मार्कर दिखाने वाले सभी ऑब्जेक्ट को ClusterItem
इंटरफ़ेस लागू करना होगा. आपके केस का मतलब है कि Place
मॉडल को ClusterItem
का पालन करना होगा. आगे बढ़ें और Place.kt
फ़ाइल खोलें और इसमें नीचे दिए गए बदलाव करें:
जगह
data class Place(
val name: String,
val latLng: LatLng,
val address: String,
val rating: Float
) : ClusterItem {
override fun getPosition(): LatLng =
latLng
override fun getTitle(): String =
name
override fun getSnippet(): String =
address
}
ClusterItem इन तीन तरीकों के बारे में बताता है:
getPosition()
, जो जगहLatLng
का प्रतिनिधित्व करता है.getTitle()
, जो जगह के नाम #39 दिखाता हैgetSnippet()
, जो जगह के पते#33 दिखाता है.
डिफ़ॉल्टClusterRenderer क्लास को सब-क्लास करें
क्लस्टर लागू करने के लिए ज़िम्मेदार क्लास, ClusterManager
, अंदरूनी तौर पर ClusterRenderer
क्लास का इस्तेमाल करता है, ताकि क्लस्टर बनाने के दौरान आप उसे पैन कर सकें और मैप को ज़ूम कर सकें. डिफ़ॉल्ट रूप से, यह डिफ़ॉल्ट रेंडरर के साथ आता है, DefaultClusterRenderer
, जो ClusterRenderer
को लागू करता है. आसान मामलों में, यह काफ़ी होना चाहिए. हालांकि, आपके मामले में, मार्कर को कस्टमाइज़ करने की ज़रूरत होती है, इसलिए आपको इस क्लास का विस्तार करना होगा और उसमें कस्टमाइज़ेशन जोड़ने होंगे.
आगे बढ़ें और पैकेज com.google.codelabs.buildyourfirstmap.place
में Kotlin फ़ाइल PlaceRenderer.kt
बनाएं और इसे इस तरह से बताएं:
जगह बनाने वाला
package com.google.codelabs.buildyourfirstmap.place
import android.content.Context
import androidx.core.content.ContextCompat
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import com.google.codelabs.buildyourfirstmap.BitmapHelper
import com.google.codelabs.buildyourfirstmap.R
import com.google.maps.android.clustering.ClusterManager
import com.google.maps.android.clustering.view.DefaultClusterRenderer
/**
* A custom cluster renderer for Place objects.
*/
class PlaceRenderer(
private val context: Context,
map: GoogleMap,
clusterManager: ClusterManager<Place>
) : DefaultClusterRenderer<Place>(context, map, clusterManager) {
/**
* The icon to use for each cluster item
*/
private val bicycleIcon: BitmapDescriptor by lazy {
val color = ContextCompat.getColor(context,
R.color.colorPrimary
)
BitmapHelper.vectorToBitmap(
context,
R.drawable.ic_directions_bike_black_24dp,
color
)
}
/**
* Method called before the cluster item (the marker) is rendered.
* This is where marker options should be set.
*/
override fun onBeforeClusterItemRendered(
item: Place,
markerOptions: MarkerOptions
) {
markerOptions.title(item.name)
.position(item.latLng)
.icon(bicycleIcon)
}
/**
* Method called right after the cluster item (the marker) is rendered.
* This is where properties for the Marker object should be set.
*/
override fun onClusterItemRendered(clusterItem: Place, marker: Marker) {
marker.tag = clusterItem
}
}
यह क्लास इन दो फ़ंक्शन को ओवरराइड करती है:
onBeforeClusterItemRendered()
, जिसे मैप पर क्लस्टर को रेंडर करने से पहले कॉल किया जाता है. यहां, आपMarkerOptions
की मदद से कस्टमाइज़ेशन कर सकते हैं—इस मामले में, यह मार्कर' का शीर्षक, पोज़िशन, और आइकॉन सेट करता है.onClusterItemRenderer()
, जिसे मार्कर के मैप पर रेंडर किए जाने के तुरंत बाद कॉल किया जाता है. यहां आप बनाए गएMarker
ऑब्जेक्ट को ऐक्सेस कर सकते हैं—इस मामले में, यह मार्कर और #39;s टैग प्रॉपर्टी को सेट करता है.
ClusterManager बनाएं और आइटम जोड़ें
आखिर में, क्लस्टर की सुविधा पाने के लिए, आपको MainActivity
में बदलाव करना होगा, ताकि ClusterManager
को इंस्टैंशिएट किया जा सके और उस पर ज़रूरी डिपेंडेंसी दी जा सके. ClusterManager
, मार्कर (ClusterItem
ऑब्जेक्ट) को अंदरूनी तौर पर जोड़ने का काम करता है. इसलिए, मैप पर सीधे मार्कर जोड़ने के बजाय, इस ज़िम्मेदारी को ClusterManager
में शामिल किया जाता है. इसके अलावा, ClusterManager
setInfoWindowAdapter()
के अंदर भी कॉल कर सकते हैं. इसलिए, कस्टम जानकारी वाली विंडो को ClusterManger
's MarkerManager.Collection
ऑब्जेक्ट पर सेट किया जाना होगा.
- शुरू करने के लिए,
MainActivity.onCreate()
केgetMapAsync()
कॉल में Lambda के कॉन्टेंट में बदलाव करें. आगे बढ़ें औरaddMarkers()
औरsetInfoWindowAdapter()
पर कॉल को टिप्पणी करें. इसके बजाय,addClusteredMarkers()
नाम का एक तरीका शुरू करें, जिसे आप आगे तय करते हैं.
MainActivity.onCreate()
mapFragment?.getMapAsync { googleMap ->
//addMarkers(googleMap)
addClusteredMarkers(googleMap)
// Set custom info window adapter.
// googleMap.setInfoWindowAdapter(MarkerInfoWindowAdapter(this))
}
- इसके बाद,
MainActivity
मेंaddClusteredMarkers()
के बारे में बताएं.
MainActivity.addClusteredMarkers()
/**
* Adds markers to the map with clustering support.
*/
private fun addClusteredMarkers(googleMap: GoogleMap) {
// Create the ClusterManager class and set the custom renderer.
val clusterManager = ClusterManager<Place>(this, googleMap)
clusterManager.renderer =
PlaceRenderer(
this,
googleMap,
clusterManager
)
// Set custom info window adapter
clusterManager.markerCollection.setInfoWindowAdapter(MarkerInfoWindowAdapter(this))
// Add the places to the ClusterManager.
clusterManager.addItems(places)
clusterManager.cluster()
// Set ClusterManager as the OnCameraIdleListener so that it
// can re-cluster when zooming in and out.
googleMap.setOnCameraIdleListener {
clusterManager.onCameraIdle()
}
}
इस तरीके से ClusterManager
को इंस्टैंशिएट किया जाता है, कस्टम रेंडरर को PlacesRenderer
भेजा जाता है, सभी जगहों को जोड़ा जाता है, और cluster()
तरीके को शुरू किया जाता है. साथ ही, ClusterManager
, मैप ऑब्जेक्ट पर setInfoWindowAdapter()
तरीके का इस्तेमाल करता है. इसलिए, कस्टम ऑब्जेक्ट विंडो को ClusterManager.markerCollection
ऑब्जेक्ट पर सेट करना होगा. आखिर में, जब आप उपयोगकर्ता के मैप पर पैन और ज़ूम करने के लिए क्लस्टरिंग बदलना चाहते हैं, तो googleMap
को OnCameraIdleListener
दिया जाता है, जैसे कि जब कैमरा इस्तेमाल में नहीं होता, तो clusterManager.onCameraIdle()
को शुरू किया जाता है.
- क्लस्टर की नई दुकानें देखने के लिए, ऐप्लिकेशन का इस्तेमाल करें!
9. मैप पर जानकारी देने के लिए ड्रॉ करें
जब आप मैप पर बनाने के लिए पहले से ही एक तरीका एक्सप्लोर कर चुके हैं, तब Android के लिए Maps SDK टूल कई दूसरे तरीकों से इस पर काम कर सकता है. जैसे, मैप पर काम की जानकारी दिखाने के लिए.
उदाहरण के लिए, अगर आप मैप पर रास्ते और इलाके दिखाना चाहते हैं, तो उन्हें पॉलीलाइन और पॉलीगॉन का इस्तेमाल करके मैप पर दिखा सकते हैं. इसके अलावा, अगर आप कोई इमेज ज़मीन की सतह पर ठीक करना चाहते हैं, तो आप ग्राउंड ओवरले का इस्तेमाल कर सकते हैं.
इस टास्क में, आप मार्कर को टैप करने पर उसके आकार (खास तौर पर सर्कल) को बनाने का तरीका जानेंगे.
क्लिक लिसनर जोड़ें
आम तौर पर, आप मार्कर के ज़रिए क्लिक लिसनर जोड़ने का तरीका, GoogleMap
के ज़रिए सीधे setOnMarkerClickListener()
ऑब्जेक्ट पर setOnMarkerClickListener()
लिसनर के ज़रिए पास करते हैं. हालांकि, क्योंकि आप क्लस्टर का इस्तेमाल कर रहे हैं, इसलिए क्लिक लिसनर ClusterManager
को दिया जाना चाहिए.
MainActivity
मेंaddClusteredMarkers()
तरीके में,cluster()
को शुरू करने के तुरंत बाद नीचे दी गई लाइन जोड़ें.
MainActivity.addClusteredMarkers()
// Show polygon
clusterManager.setOnClusterItemClickListener { item ->
addCircle(googleMap, item)
return@setOnClusterItemClickListener false
}
इस तरीके से लिसनर जोड़ा जाता है और addCircle()
मैथड को शुरू किया जाता है. आखिर में, यह बताने के लिए कि इस तरीके ने इस इवेंट का इस्तेमाल नहीं किया है, false
को इस तरीके से लौटा दिया जाता है.
- इसके बाद, आपको
MainActivity
में प्रॉपर्टीcircle
और तरीकाaddCircle()
तय करना होगा.
MainActivity.addCircle()
private var circle: Circle? = null
/**
* Adds a [Circle] around the provided [item]
*/
private fun addCircle(googleMap: GoogleMap, item: Place) {
circle?.remove()
circle = googleMap.addCircle(
CircleOptions()
.center(item.latLng)
.radius(1000.0)
.fillColor(ContextCompat.getColor(this, R.color.colorPrimaryTranslucent))
.strokeColor(ContextCompat.getColor(this, R.color.colorPrimary))
)
}
circle
प्रॉपर्टी को सेट किया जाता है, ताकि जब भी किसी नए मार्कर पर टैप किया जाए, तो पिछला सर्कल हटा दिया जाए और एक नया मार्कर जोड़ दिया जाए. ध्यान दें कि सर्कल जोड़ने के लिए एपीआई, काफ़ी हद तक मार्कर जोड़ने जैसा ही है.
- आगे बढ़ें और बदलाव देखने के लिए ऐप्लिकेशन चलाएं.
10. कैमरा कंट्रोल
अपने आखिरी टास्क के तौर पर, आप कैमरे के कुछ कंट्रोल देखते हैं, ताकि आप किसी खास इलाके के आस-पास के व्यू पर फ़ोकस कर सकें.
कैमरा और व्यू
जब आप ऐप्लिकेशन चलाते हैं, तो कैमरा अफ़्रीका महाद्वीप दिखाता है. साथ ही, आपने जो मार्कर जोड़े हैं उन्हें ढूंढने के लिए आपको बहुत मेहनत से पैन और ज़ूम से सैन फ़्रांसिस्को जाना होगा. दुनिया को एक्सप्लोर करने का यह एक मज़ेदार तरीका हो सकता है. हालांकि, अगर आप मार्कर को तुरंत दिखाना चाहते हैं, तो यह काम का नहीं है.
इस काम में मदद करने के लिए, आप कैमरे की स्थिति को प्रोग्रामैटिक तरीके से सेट कर सकते हैं, ताकि व्यू अपने हिसाब से बीच में हो.
- कैमरे के व्यू में बदलाव करने के लिए,
getMapAsync()
कॉल में आगे दिया गया कोड जोड़ें, ताकि ऐप्लिकेशन लॉन्च होने पर यह सैन फ़्रांसिस्को की जगह पर शुरू हो सके.
MainActivity.onCreate()
mapFragment?.getMapAsync { googleMap ->
// Ensure all places are visible in the map.
googleMap.setOnMapLoadedCallback {
val bounds = LatLngBounds.builder()
places.forEach { bounds.include(it.latLng) }
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 20))
}
}
पहले, setOnMapLoadedCallback()
को कॉल किया जाता है, ताकि कैमरा अपडेट सिर्फ़ मैप लोड होने के बाद ही किया जा सके. यह चरण ज़रूरी है, क्योंकि कैमरा अपडेट कॉल करने से पहले, डाइमेंशन जैसी मैप प्रॉपर्टी का हिसाब लगाना होता है.
Lambda में, एक नया LatLngBounds
ऑब्जेक्ट बनाया गया है, जो मैप पर एक आयताकार क्षेत्र बताता है. सभी जगहों की सीमाओं के अंदर पक्का करने के लिए, इसमें सभी जगह LatLng
की वैल्यू शामिल करके इसे लगातार बनाया जाता है. इस ऑब्जेक्ट के बन जाने के बाद, GoogleMap
पर moveCamera()
तरीके को शुरू किया जाता है और CameraUpdateFactory.newLatLngBounds(bounds.build(), 20)
के ज़रिए इसे CameraUpdate
दिया जाता है.
- ऐप्लिकेशन खोलें और देखें कि कैमरा अब सैन फ़्रांसिस्को में शुरू हो गया है.
कैमरे में हुए बदलावों पर ध्यान देना
कैमरे की स्थिति को बदलने के अलावा, आप उपयोगकर्ता के मैप पर इधर-उधर जाने पर भी कैमरे के अपडेट सुन सकते हैं. अगर आपका कैमरा आस-पास घूमता है, तो आपको यूज़र इंटरफ़ेस (यूआई) में बदलाव करना पड़ सकता है.
सिर्फ़ मनोरंजन के लिए, कैमरा चलते समय मार्कर को पारदर्शी बनाने के लिए आप कोड में बदलाव करते हैं.
addClusteredMarkers()
तरीके में, आगे बढ़ें और पैसे चुकाने के तरीके के सबसे नीचे की ओर ये लाइनें जोड़ें:
MainActivity.addClusteredMarkers()
// When the camera starts moving, change the alpha value of the marker to translucent.
googleMap.setOnCameraMoveStartedListener {
clusterManager.markerCollection.markers.forEach { it.alpha = 0.3f }
clusterManager.clusterMarkerCollection.markers.forEach { it.alpha = 0.3f }
}
इससे OnCameraMoveStartedListener
जुड़ जाता है, ताकि जब भी कैमरा चलना शुरू करे, तो सभी मार्कर' (क्लस्टर और मार्कर) ऐल्फ़ा मान 0.3f
में बदल जाएं, ताकि मार्कर पारदर्शी दिखें.
- आखिर में, कैमरा बंद होने पर ट्रांसपेरंट मार्कर को वापस अपारदर्शिता में बदलने के लिए,
addClusteredMarkers()
तरीके मेंsetOnCameraIdleListener
के कॉन्टेंट में यह बदलाव करें:
MainActivity.addClusteredMarkers()
googleMap.setOnCameraIdleListener {
// When the camera stops moving, change the alpha value back to opaque.
clusterManager.markerCollection.markers.forEach { it.alpha = 1.0f }
clusterManager.clusterMarkerCollection.markers.forEach { it.alpha = 1.0f }
// Call clusterManager.onCameraIdle() when the camera stops moving so that reclustering
// can be performed when the camera stops moving.
clusterManager.onCameraIdle()
}
- आगे बढ़ें और नतीजे देखने के लिए ऐप्लिकेशन चलाएं!
11. मैप KTX
Kotlin ऐप्लिकेशन के एक या एक से ज़्यादा Google Maps Platform Android SDK टूल का इस्तेमाल करने वाले, Kotlin एक्सटेंशन या KTX लाइब्रेरी उपलब्ध हैं. इनसे कोरूटीन, एक्सटेंशन प्रॉपर्टी/फ़ंक्शन वगैरह जैसी Kotlin लैंग्वेज की सुविधाओं का फ़ायदा लिया जा सकता है. हर Google Maps SDK टूल में उससे जुड़ी एक KTX लाइब्रेरी मौजूद है, जैसा कि नीचे दिखाया गया है:
इस टास्क में, आप Maps KTX और Maps Utils KTX लाइब्रेरी का इस्तेमाल अपने ऐप्लिकेशन के लिए करेंगे. साथ ही, पिछले टास्क' को रीफ़ैक्टर करेंगे; ताकि आप अपने ऐप्लिकेशन में Kotlin की खास भाषाओं की सुविधाओं का इस्तेमाल कर सकें.
- अपने ऐप्लिकेशन-लेवल build.gradle फ़ाइल में KTX डिपेंडेंसी शामिल करना
ऐप्लिकेशन, Android के लिए Maps SDK और Android Utility लाइब्रेरी के लिए Maps SDK टूल, दोनों का इस्तेमाल करता है. इसलिए, आपको इन लाइब्रेरी से जुड़ी KTX लाइब्रेरी शामिल करनी होंगी. इस टास्क में, AndroidX Lifecycle KTX लाइब्रेरी में मौजूद सुविधा का भी इस्तेमाल किया जाएगा. इसलिए, यह निर्भरता भी अपने ऐप्लिकेशन में build.gradle
फ़ाइल में शामिल करें.
build.gradle
dependencies {
// ...
// Maps SDK for Android KTX Library
implementation 'com.google.maps.android:maps-ktx:3.0.0'
// Maps SDK for Android Utility Library KTX Library
implementation 'com.google.maps.android:maps-utils-ktx:3.0.0'
// Lifecycle Runtime KTX Library
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
}
- GoogleMap.addmarker() और GoogleMap.addCircle() एक्सटेंशन फ़ंक्शन का इस्तेमाल करना
Maps KTX लाइब्रेरी पिछले और इस्तेमाल किए गए GoogleMap.addMarker(MarkerOptions)
और GoogleMap.addCircle(CircleOptions)
के लिए, DSL-शैली का एपीआई विकल्प देती है. ऊपर बताए गए एपीआई का इस्तेमाल करने के लिए, मार्कर या सर्कल के विकल्प वाली क्लास बनाना ज़रूरी है, जबकि KTX विकल्पों के साथ आप lambda में मार्कर या सर्कल के विकल्प सेट कर सकते हैं.
इन एपीआई का इस्तेमाल करने के लिए, MainActivity.addMarkers(GoogleMap)
और MainActivity.addCircle(GoogleMap)
के तरीके अपडेट करें:
MainActivity.addmarkers(GoogleMap)
/**
* Adds markers to the map. These markers won't be clustered.
*/
private fun addMarkers(googleMap: GoogleMap) {
places.forEach { place ->
val marker = googleMap.addMarker {
title(place.name)
position(place.latLng)
icon(bicycleIcon)
}
// Set place as the tag on the marker object so it can be referenced within
// MarkerInfoWindowAdapter
marker.tag = place
}
}
MainActivity.addCircle(GoogleMap)
/**
* Adds a [Circle] around the provided [item]
*/
private fun addCircle(googleMap: GoogleMap, item: Place) {
circle?.remove()
circle = googleMap.addCircle {
center(item.latLng)
radius(1000.0)
fillColor(ContextCompat.getColor(this@MainActivity, R.color.colorPrimaryTranslucent))
strokeColor(ContextCompat.getColor(this@MainActivity, R.color.colorPrimary))
}
}
ऊपर दिए गए तरीकों से इस तरीके को फिर से लिखना बहुत आसान है. साथ ही, इसे Kotlin और #39;s रेंडर वाले फ़ंक्शन के साथ लिटरल का इस्तेमाल करके पढ़ना मुमकिन है.
- SupportMapFragment.awaitMap() और GoogleMap.awaitMapLoad() एक्सटेंशन सस्पेंडिंग फ़ंक्शन का इस्तेमाल करना
Maps KTX लाइब्रेरी, कोरूटीन के लिए इस्तेमाल किए जाने वाले सस्पेंड फ़ंक्शन एक्सटेंशन भी उपलब्ध कराती है. खास तौर पर, हम SupportMapFragment.getMapAsync(OnMapReadyCallback)
और GoogleMap.setOnMapLoadedCallback(OnMapLoadedCallback)
के लिए, फ़ंक्शन के विकल्प निलंबित कर रहे हैं. इन वैकल्पिक एपीआई का इस्तेमाल करने से कॉलबैक पास करने की ज़रूरत नहीं होती. साथ ही, आपको सीरियल और सिंक्रोनस तरीके से इन तरीकों का जवाब पाने की सुविधा मिलती है.
ये तरीके फ़ंक्शन को निलंबित कर रहे हैं, इसलिए उनका इस्तेमाल कोरूटीन के अंदर होना चाहिए. लाइफ़साइकल रनटाइम KTX लाइब्रेरी, लाइफ़साइकल की जानकारी वाले कोरूटीन स्कोप उपलब्ध कराने के लिए, एक्सटेंशन ऑफ़र करती है, ताकि कोरूटीन चलाए जाने पर उन्हें सही लाइफ़साइकल इवेंट में रोका और रोका जा सके.
इन सिद्धांतों को मिलाकर, MainActivity.onCreate(Bundle)
तरीका अपडेट करें:
MainActivity.onCreate(बंडल)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mapFragment =
supportFragmentManager.findFragmentById(R.id.map_fragment) as SupportMapFragment
lifecycleScope.launchWhenCreated {
// Get map
val googleMap = mapFragment.awaitMap()
// Wait for map to finish loading
googleMap.awaitMapLoad()
// Ensure all places are visible in the map
val bounds = LatLngBounds.builder()
places.forEach { bounds.include(it.latLng) }
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 20))
addClusteredMarkers(googleMap)
}
}
lifecycleScope.launchWhenCreated
कोरूटीन का दायरा, ब्लॉक को एक्ज़ीक्यूट करेगा, जब गतिविधि कम से कम तय की गई स्थिति में होगी. यह भी ध्यान रखें कि GoogleMap
ऑब्जेक्ट को वापस पाने और मैप के लोड होने तक इंतज़ार करने के लिए, कॉल को SupportMapFragment.awaitMap()
और GoogleMap.awaitMapLoad()
से बदल दिया गया है. सस्पेंड करने के इन फ़ंक्शन का इस्तेमाल करके, कोड को रीफ़ैक्ट करने में मदद मिलती है. इसकी मदद से, आप एक जैसे क्रम में, एक जैसे कॉलबैक वाले कोड लिख सकते हैं.
- आगे बढ़ें और रीफ़ैक्टर किए गए बदलावों के साथ ऐप्लिकेशन को फिर से बनाएं!
12. बधाई हो
बधाई हो! आपने बहुत सारा कॉन्टेंट कवर किया है और उम्मीद है कि आपको Android के लिए Maps SDK में दी गई मुख्य सुविधाओं की बेहतर जानकारी होगी.
ज़्यादा जानें
- Android के लिए जगहें SDK टूल—अपने आस-पास के कारोबारों का पता लगाने के लिए, जगहों के डेटा का रिच सेट देखें.
- android-maps-ktx—एक ओपन सोर्स लाइब्रेरी है, जिसकी मदद से आप Android के लिए Maps SDK टूल और Android Utility लाइब्रेरी के लिए Maps SDK टूल को Kotlin के साथ आसानी से इस्तेमाल करने लायक बना सकते हैं.
- android-place-ktx—एक ओपन सोर्स लाइब्रेरी, जो आपको Kotlin के हिसाब से Android के लिए जगहें SDK टूल के साथ इंटिग्रेट करने की अनुमति देती है.
- android-samples—GitHub के सैंपल कोड में, इस कोडलैब में शामिल सभी सुविधाओं के बारे में बताया गया है.
- Google Maps Platform की मदद से Android ऐप्लिकेशन बनाने के लिए, Kotlin कोडलैब की ज़्यादा जानकारी