MapView का जीवनचक्र और ईवेंट
नक्शा को दो चीजों से नियंत्रित किया जाता है: व्यू और स्टेट ऑब्जेक्ट। स्टेट (mapViewState) कैमरा, डिज़ाइन और इंटरैक्शन का इंटरफ़ेस है, जबकि व्यू को केवल प्रत्येक प्लेटफ़ॉर्म के UI ट्री में रखा जाता है। इनिशियलाइज़ेशन सामान्य चरणों में होता है, और लोडिंग पूरी होने और यूज़र इंटरैक्शन को ईवेंट के रूप में प्राप्त किया जाता है।
01 · mapViewState
mapViewState एक नक्शे के लिए स्टेट ऑब्जेक्ट है। प्रत्येक प्रोवाइडर का अपना कार्यान्वयन होता है, लेकिन सार्वजनिक सदस्य समान होते हैं, और ऐप कोड को केवल सामान्य इंटरफ़ेस पर ध्यान केंद्रित करने की आवश्यकता होती है।
स्टेट व्यू से अधिक समय तक जीवित रहता है। भले ही व्यू पुनः बनाया जाए, कैमरा स्थिति और डिज़ाइन स्टेट पक्ष में बनी रहती है, इसलिए नक्शा यथावत पुनर्स्थापित हो जाता है।
// स्टेट remember* से बनाएँ, ताकि स्क्रीन घूमने पर भी वही मैप लौटे
val mapViewState =
rememberGoogleMapViewState(
mapDesign = GoogleMapDesign.Normal,
cameraPosition = initCameraPosition,
)
GoogleMapView(state = mapViewState, modifier = Modifier.fillMaxSize())// ObservableObject है: @StateObject से View में रखें
@StateObject private var mapLibreState = MapLibreViewState(
mapDesignType: MapLibreDesign.OsmBright,
cameraPosition: viewModel.initCameraPosition
)
MapLibreMapView(state: mapLibreState) { MapViewContent() }const [mapViewState, setMapViewState] =
useState<MapViewStateInterface<MapDesignTypeInterface<unknown>> | null>(null);
// MapViewContainer सैंपल ऐप का प्रोवाइडर बदलने वाला रैपर है — SDK के साथ नहीं आता
<MapViewContainer provider={provider} cameraPosition={INIT_CAMERA} onStateReady={setMapViewState}>
<Markers states={markerStates} />
</MapViewContainer>02 · इनिशियलाइज़ेशन का जीवनचक्र
नक्शे का इनिशियलाइज़ेशन किसी भी प्रोवाइडर के लिए समान चरणों का अनुसरण करता है। SDK लोड होना, व्यू बनना, मैप इंस्टेंस बनना, और फिर टाइल्स रेंडरिंग पूरा होना। चरणों को InitState के रूप में सामान्यीकृत किया गया है, इसलिए आपको "अभी तक हेरफेर नहीं करने की अवधि" को प्रोवाइडर के आधार पर याद रखने की आवश्यकता नहीं है।
कैमरा ऑपरेशन और ओवरले जोड़ना MapCreated के बाद स्वीकार किए जाते हैं और आंतरिक रूप से कतारबद्ध होते हैं। लोडिंग पूरी होने का इंतज़ार करने के बाद कुछ करने के लिए onMapLoaded का उपयोग करें।
मानचित्र SDK लोड करता है। वेब पर स्क्रिप्ट इंजेक्शन, मोबाइल पर आरंभीकरण प्रक्रिया। विफल होने पर Failed में आगे बढ़ता है।
नेटिव मानचित्र इंस्टैंस को होल्डर में लपेटता है। इसके बाद, SDK-विशिष्ट प्रकार यहां छिप जाते हैं।
होल्डर को कंट्रोलर से लपेटता है और सामान्य API और इवेंट वायरिंग तैयार करता है। स्थिति से कंट्रोलर जुड़ा होता है।
स्क्रीन रोटेशन / पुनर्निर्माण के पार
Android में स्थिति rememberSaveable में सहेजी जाती है, और स्क्रीन रोटेशन या कॉन्फ़िगरेशन बदलने के बाद भी कैमरा की स्थिति और डिज़ाइन पुनर्स्थापित होता है। कॉन्फ़िगरेशन बदलने के दौरान मानचित्र दृश्य को नष्ट नहीं करके पुन: उपयोग किया जाता है।
नष्ट किए जाने पर
वास्तविक निस्तारण (स्क्रीन छोड़ना) में कंट्रोलर द्वारा ओवरले प्रबंधन, टाइल सर्वर के मार्ग, और कोरूटीन स्कोप को एक साथ मुक्त किया जाता है। प्रदाता बदलने पर भी उसी मार्ग से पुराना मानचित्र साफ़ किया जाता है।
var ready by remember { mutableStateOf(false) }
MapLibreMapView(
state = mapViewState,
// Called once, when the tiles have finished drawing
onMapLoaded = { state ->
ready = true
state.fitBounds(routeBounds, padding = 48)
},
) {
// Declarations here are not lost before MapCreated — they are queued internally
Marker(markerState)
}
if (!ready) {
// Your own loading overlay, if you want one. The map does not need blocking
Box(Modifier.fillMaxSize()) { CircularProgressIndicator() }
}03 · ईवेंट
व्यू को पास किए जाने वाले हैंडलर तीनों प्लेटफ़ॉर्म पर समान संरचना के होते हैं। प्रकार भी समान हैं, लोडिंग पूरी होना स्टेट ऑब्जेक्ट प्राप्त करता है, टैप निर्देशांक प्राप्त करता है, और कैमरा परिवर्तन कैमरा स्थिति प्राप्त करता है।
GoogleMapView(
state = mapViewState,
onMapLoaded = { state -> viewModel.onMapLoaded(state) },
onMapClick = { point -> viewModel.onMapClick(point) },
onCameraMove = { camera -> viewModel.onCameraChanged(camera) },
onCameraMoveEnd = { camera -> viewModel.onCameraSettled(camera) },
) { /* markers, overlays */ }MapLibreMapView(
state: mapLibreState,
onMapLoaded: { state in viewModel.onMapLoaded(state) },
onCameraMoveStart: viewModel.onMapCameraMoveStart,
onCameraMove: viewModel.onCameraChanged,
onCameraMoveEnd: viewModel.onMapCameraMoveEnd
) {
MapViewContent()
}<MapViewContainer
provider={provider}
cameraPosition={INIT_CAMERA}
onMapClick={() => setSelected(null)}
onCameraMove={setCameraPosition}
>
<Markers states={markerStates} />
</MapViewContainer>कैमरा प्रकार के ईवेंट स्थिति वस्तु के cameraPosition को भी एक साथ अपडेट करते हैं, इसलिए हैंडलर लगाए बिना भी नवीनतम कैमरा हमेशा पढ़ा जा सकता है। स्थानांतरण के दौरान पुनः प्राप्त करने से बचना चाहते हैं तो कृपया केवल onCameraMoveEnd का उपयोग करें।
04 · नेटिव के लिए भागने का रास्ता
सामान्य API के पर्याप्त न होने पर, नेटिव मानचित्र इंस्टेंस पर जाने के लिए एक रास्ता तैयार किया गया है। आमतौर पर इसका उपयोग नहीं किया जाता है, लेकिन यदि आप प्रदाता-विशिष्ट सुविधा का उपयोग केवल एक जगह पर करना चाहते हैं तो यह एक भागने का रास्ता है।
नेटिव मानचित्र को लपेटने वाला होल्डर
होल्डर में प्लेटफ़ॉर्म का व्यू और मानचित्र इंस्टैंस — ये दो चीज़ें होती हैं। SDK-विशिष्ट कोड को यहां से आगे कैद करके, सामान्य कोड में लीक न होने देने की व्यवस्था है।
निर्देशांक और स्क्रीन स्थिति का रूपांतरण
भौगोलिक निर्देशांक और स्क्रीन पर पिक्सेल स्थिति को आपस में बदला जा सकता है। मानचित्र के ऊपर कस्टम UI ओवरले करते समय इसका उपयोग किया जाता है।
// सिर्फ़ तभी निकालें जब नेटिव API सचमुच चाहिए val holder = mapViewState.getMapViewHolder() val nativeMap = holder?.map // GoogleMap / MapLibreMap / ... val offset = holder?.toScreenOffset(point)
if let holder = mapViewState.getMapViewHolder() {
let nativeMap = holder.map
let offset = holder.toScreenOffset(position: point)
}const holder = mapViewState.getMapViewHolder(); const nativeMap = holder?.map; // google.maps.Map / maplibregl.Map / ...
होल्डर का उपयोग करने वाला कोड प्रदाता पर निर्भर करता है। सामान्य रूप से बनाए रखने के लिए भाग और जानबूझकर विशिष्ट API का उपयोग करने वाले भाग को ध्यान से अलग करें।