mirror of
https://github.com/googlemaps/android-samples.git
synced 2025-12-08 18:02:20 +00:00
feat: Add SaveStateDemoActivity. (#431)
This commit is contained in:
parent
05b53a22d6
commit
0514d79efa
@ -52,6 +52,7 @@
|
||||
<activity android:name=".ProgrammaticDemoActivity" />
|
||||
<activity android:name=".RawMapViewDemoActivity" />
|
||||
<activity android:name=".RetainMapDemoActivity" />
|
||||
<activity android:name=".SaveStateDemoActivity" />
|
||||
<activity android:name=".SplitStreetViewPanoramaAndMapDemoActivity" />
|
||||
<activity android:name=".StreetViewPanoramaBasicDemoActivity" />
|
||||
<activity android:name=".StreetViewPanoramaEventsDemoActivity" />
|
||||
|
||||
@ -23,8 +23,6 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.GoogleMap.OnCameraIdleListener
|
||||
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
|
||||
@ -33,7 +31,6 @@ import com.google.maps.android.ktx.CameraIdleEvent
|
||||
import com.google.maps.android.ktx.awaitMap
|
||||
import com.google.maps.android.ktx.cameraEvents
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@ -86,6 +86,9 @@ class DemoDetailsList {
|
||||
DemoDetails(R.string.raw_map_view_demo_label,
|
||||
R.string.raw_map_view_demo_description,
|
||||
RawMapViewDemoActivity::class.java),
|
||||
DemoDetails(R.string.save_state_demo_label,
|
||||
R.string.save_state_demo_description,
|
||||
SaveStateDemoActivity::class.java),
|
||||
DemoDetails(R.string.street_view_panorama_basic_demo_label,
|
||||
R.string.street_view_panorama_basic_demo_details,
|
||||
StreetViewPanoramaBasicDemoActivity::class.java),
|
||||
|
||||
@ -0,0 +1,160 @@
|
||||
// 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.kotlindemos
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener
|
||||
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener
|
||||
import com.google.android.gms.maps.SupportMapFragment
|
||||
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.Marker
|
||||
import com.google.maps.android.ktx.CameraEvent
|
||||
import com.google.maps.android.ktx.addMarker
|
||||
import com.google.maps.android.ktx.awaitMap
|
||||
import com.google.maps.android.ktx.cameraEvents
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import java.util.Random
|
||||
|
||||
/**
|
||||
* This activity shows how to save the state of a MapFragment when the activity is recreated, like
|
||||
* after rotation of the device.
|
||||
*/
|
||||
class SaveStateDemoActivity : AppCompatActivity() {
|
||||
|
||||
@Parcelize
|
||||
internal data class MarkerInfo(var hue: Float) : Parcelable
|
||||
|
||||
/**
|
||||
* Example of a custom `MapFragment` showing how the position of a marker and other
|
||||
* custom
|
||||
* [Parcelable]s objects can be saved after rotation of the device.
|
||||
*
|
||||
*
|
||||
* Storing custom [Parcelable] objects directly in the [Bundle] provided by the
|
||||
* [.onActivityCreated] method will throw a `ClassNotFoundException`. This
|
||||
* is due to the fact that this Bundle is parceled (thus losing its ClassLoader attribute at
|
||||
* this moment) and unparceled later in a different ClassLoader.
|
||||
* <br></br>
|
||||
* A workaround to store these objects is to wrap the custom [Parcelable] objects in a
|
||||
* new
|
||||
* [Bundle] object.
|
||||
*
|
||||
*
|
||||
* However, note that it is safe to store [Parcelable] objects from the Maps API (eg.
|
||||
* MarkerOptions, LatLng, etc.) directly in the Bundle provided by the
|
||||
* [.onActivityCreated] method.
|
||||
*/
|
||||
class SaveStateMapFragment : SupportMapFragment(), OnMarkerClickListener, OnMarkerDragListener {
|
||||
|
||||
private lateinit var mMarkerPosition: LatLng
|
||||
private lateinit var mMarkerInfo: MarkerInfo
|
||||
private var mMoveCameraToMarker = false
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// Extract the state of the MapFragment:
|
||||
// - Objects from the API (eg. LatLng, MarkerOptions, etc.) were stored directly in
|
||||
// the savedInsanceState Bundle.
|
||||
// - Custom Parcelable objects were wrapped in another Bundle.
|
||||
mMarkerPosition =
|
||||
savedInstanceState?.getParcelable(MARKER_POSITION) ?: DEFAULT_MARKER_POSITION
|
||||
mMarkerInfo =
|
||||
savedInstanceState?.getBundle(OTHER_OPTIONS)?.getParcelable(MARKER_INFO) ?: MarkerInfo(
|
||||
BitmapDescriptorFactory.HUE_RED)
|
||||
mMoveCameraToMarker = savedInstanceState == null
|
||||
|
||||
lifecycleScope.launchWhenCreated {
|
||||
val map = awaitMap()
|
||||
map.addMarker {
|
||||
icon(BitmapDescriptorFactory.defaultMarker(mMarkerInfo.hue))
|
||||
position(mMarkerPosition)
|
||||
draggable(true)
|
||||
}
|
||||
|
||||
map.setOnMarkerDragListener(this@SaveStateMapFragment)
|
||||
map.setOnMarkerClickListener(this@SaveStateMapFragment)
|
||||
|
||||
if (mMoveCameraToMarker) {
|
||||
map.animateCamera(CameraUpdateFactory.newLatLng(mMarkerPosition))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
// All Parcelable objects of the API (eg. LatLng, MarkerOptions, etc.) can be set
|
||||
// directly in the given Bundle.
|
||||
outState.putParcelable(MARKER_POSITION, mMarkerPosition)
|
||||
|
||||
// All other custom Parcelable objects must be wrapped in another Bundle. Indeed,
|
||||
// failing to do so would throw a ClassNotFoundException. This is due to the fact that
|
||||
// this Bundle is being parceled (losing its ClassLoader at this time) and unparceled
|
||||
// later in a different ClassLoader.
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable(MARKER_INFO, mMarkerInfo)
|
||||
outState.putBundle(OTHER_OPTIONS, bundle)
|
||||
}
|
||||
|
||||
override fun onMarkerClick(marker: Marker): Boolean {
|
||||
val newHue = MARKER_HUES[Random()
|
||||
.nextInt(MARKER_HUES.size)]
|
||||
mMarkerInfo.hue = newHue
|
||||
marker.setIcon(BitmapDescriptorFactory.defaultMarker(newHue))
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMarkerDragStart(marker: Marker) {}
|
||||
override fun onMarkerDrag(marker: Marker) {}
|
||||
override fun onMarkerDragEnd(marker: Marker) {
|
||||
mMarkerPosition = marker.position
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.save_state_demo)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** Default marker position when the activity is first created. */
|
||||
private val DEFAULT_MARKER_POSITION = LatLng(48.858179, 2.294576)
|
||||
|
||||
/** List of hues to use for the marker */
|
||||
private val MARKER_HUES = floatArrayOf(
|
||||
BitmapDescriptorFactory.HUE_RED,
|
||||
BitmapDescriptorFactory.HUE_ORANGE,
|
||||
BitmapDescriptorFactory.HUE_YELLOW,
|
||||
BitmapDescriptorFactory.HUE_GREEN,
|
||||
BitmapDescriptorFactory.HUE_CYAN,
|
||||
BitmapDescriptorFactory.HUE_AZURE,
|
||||
BitmapDescriptorFactory.HUE_BLUE,
|
||||
BitmapDescriptorFactory.HUE_VIOLET,
|
||||
BitmapDescriptorFactory.HUE_MAGENTA,
|
||||
BitmapDescriptorFactory.HUE_ROSE)
|
||||
|
||||
// Bundle keys.
|
||||
private const val OTHER_OPTIONS = "options"
|
||||
private const val MARKER_POSITION = "markerPosition"
|
||||
private const val MARKER_INFO = "markerInfo"
|
||||
}
|
||||
}
|
||||
33
ApiDemos/kotlin/app/src/gms/res/layout/save_state_demo.xml
Executable file
33
ApiDemos/kotlin/app/src/gms/res/layout/save_state_demo.xml
Executable file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2012 The Android Open Source Project
|
||||
|
||||
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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/instructions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save_state_instructions" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/map"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
class="com.example.kotlindemos.SaveStateDemoActivity$SaveStateMapFragment" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -310,4 +310,9 @@
|
||||
<string name="retain_map_demo_label">Retain map</string>
|
||||
<string name="retain_map_demo_description">Demonstrates how to reuse a MapFragment.</string>
|
||||
|
||||
<!-- Saved State -->
|
||||
<string name="save_state_demo_label">Save the state of a MapFragment.</string>
|
||||
<string name="save_state_demo_description">Demonstrates how to save the state of a MapFragment upon rotation of the device.</string>
|
||||
<string name="save_state_instructions">Drag the marker, tap on it to change its color and rotate the device to check that the state of the map is preserved.</string>
|
||||
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user