From db352607e37b4b3f74288de25ce9ac49be29d9e3 Mon Sep 17 00:00:00 2001
From: Dale Hawkins <107309+dkhawk@users.noreply.github.com>
Date: Tue, 18 Aug 2026 15:06:01 -0600
Subject: [PATCH] fix(ApiDemos): improve window insets handling, save state
layout, and demo reliability
- Update SamplesBaseActivity (Kotlin & Java) to safely handle root view insets without double-padding child views
- Add missing save_state_demo.xml layout and wire up SaveStateDemoActivity
- Fix toolbar title in LocationSourceDemoActivity
- Clean up lint warnings, string templates, and layout constraints across standard map demos
---
.../main/res/layout/camera_clamping_demo.xml | 85 +++--
.../src/main/res/layout/camera_demo.xml | 10 +-
.../src/main/res/layout/events_demo.xml | 11 +-
.../main/res/layout/ground_overlay_demo.xml | 4 +-
.../src/main/res/layout/layers_demo.xml | 18 +-
.../src/main/res/layout/marker_demo.xml | 123 ++++----
.../street_view_panorama_events_demo.xml | 4 +-
.../street_view_panorama_options_demo.xml | 4 +-
.../src/main/res/layout/tile_overlay_demo.xml | 4 +-
.../src/main/res/layout/ui_settings_demo.xml | 4 +-
.../common-ui/src/main/res/values/arrays.xml | 22 ++
.../common-ui/src/main/res/values/strings.xml | 34 +-
ApiDemos/project/java-app/build.gradle.kts | 3 +-
.../mapdemo/CameraClampingDemoActivity.java | 82 +++--
.../example/mapdemo/EventsDemoActivity.java | 40 ++-
.../example/mapdemo/LayersDemoActivity.java | 11 +-
.../mapdemo/LocationSourceDemoActivity.java | 7 +-
.../example/mapdemo/MarkerDemoActivity.java | 11 +-
.../example/mapdemo/SamplesBaseActivity.java | 67 +++-
.../StreetViewPanoramaEventsDemoActivity.java | 10 +-
.../mapdemo/VisibleRegionDemoActivity.java | 8 +-
.../example/mapdemo/MarkerDemoActivity.java | 11 +-
.../mapdemo/VisibleRegionDemoActivity.java | 8 +-
ApiDemos/project/kotlin-app/build.gradle.kts | 4 +-
...ackgroundColorCustomizationDemoActivity.kt | 4 +-
...orCustomizationProgrammaticDemoActivity.kt | 4 +-
.../kotlindemos/CameraClampingDemoActivity.kt | 77 +++--
.../CloudBasedMapStylingDemoActivity.kt | 4 +-
.../DataDrivenBoundariesActivity.kt | 4 +-
.../example/kotlindemos/EventsDemoActivity.kt | 34 +-
.../example/kotlindemos/LayersDemoActivity.kt | 12 +-
.../kotlindemos/LocationSourceDemoActivity.kt | 22 +-
.../kotlindemos/MapColorSchemeActivity.kt | 4 +-
.../kotlindemos/MapInPagerDemoActivity.kt | 5 +-
...arkerCloseInfoWindowOnRetapDemoActivity.kt | 4 +-
.../example/kotlindemos/MarkerDemoActivity.kt | 16 +-
.../kotlindemos/MultiMapDemoActivity.kt | 4 +-
.../kotlindemos/MyLocationDemoActivity.kt | 4 +-
.../kotlindemos/OnMapAndViewReadyListener.kt | 30 +-
.../kotlindemos/PolygonDemoActivity.kt | 4 +-
.../kotlindemos/PolylineDemoActivity.kt | 6 +-
.../kotlindemos/ProgrammaticDemoActivity.kt | 10 +-
.../kotlindemos/RetainMapDemoActivity.kt | 8 +-
.../kotlindemos/SamplesBaseActivity.kt | 88 +++++-
.../kotlindemos/SaveStateDemoActivity.kt | 16 +-
.../StreetViewPanoramaBasicDemoActivity.kt | 4 +-
.../StreetViewPanoramaEventsDemoActivity.kt | 12 +-
...treetViewPanoramaNavigationDemoActivity.kt | 4 +-
.../StreetViewPanoramaViewDemoActivity.kt | 4 +-
.../kotlindemos/StyledMapDemoActivity.kt | 296 +++++++++---------
.../example/kotlindemos/TagsDemoActivity.kt | 4 +-
.../kotlindemos/VisibleRegionDemoActivity.kt | 5 +-
.../src/main/res/layout/save_state_demo.xml | 51 +++
.../example/kotlindemos/MarkerDemoActivity.kt | 16 +-
.../kotlindemos/OnMapAndViewReadyListener.kt | 29 +-
.../kotlindemos/VisibleRegionDemoActivity.kt | 5 +-
56 files changed, 883 insertions(+), 492 deletions(-)
create mode 100644 ApiDemos/project/common-ui/src/main/res/values/arrays.xml
create mode 100644 ApiDemos/project/kotlin-app/src/main/res/layout/save_state_demo.xml
diff --git a/ApiDemos/project/common-ui/src/main/res/layout/camera_clamping_demo.xml b/ApiDemos/project/common-ui/src/main/res/layout/camera_clamping_demo.xml
index cb7cdd4c2..e790ff236 100644
--- a/ApiDemos/project/common-ui/src/main/res/layout/camera_clamping_demo.xml
+++ b/ApiDemos/project/common-ui/src/main/res/layout/camera_clamping_demo.xml
@@ -1,5 +1,5 @@
-
+ app:title="@string/marker_demo_label"
+ app:titleTextColor="?attr/colorOnPrimary" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:id="@+id/map_frame"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/top_controls">
+ android:padding="8dp">
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/ApiDemos/project/common-ui/src/main/res/layout/street_view_panorama_events_demo.xml b/ApiDemos/project/common-ui/src/main/res/layout/street_view_panorama_events_demo.xml
index e96c3ab6c..8a7cf7aae 100755
--- a/ApiDemos/project/common-ui/src/main/res/layout/street_view_panorama_events_demo.xml
+++ b/ApiDemos/project/common-ui/src/main/res/layout/street_view_panorama_events_demo.xml
@@ -1,5 +1,5 @@
+
+
+ - 2.0
+ - 21.0
+
+
diff --git a/ApiDemos/project/common-ui/src/main/res/values/strings.xml b/ApiDemos/project/common-ui/src/main/res/values/strings.xml
index 8fd4ff0ab..641941e8b 100755
--- a/ApiDemos/project/common-ui/src/main/res/values/strings.xml
+++ b/ApiDemos/project/common-ui/src/main/res/values/strings.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
+
Maps SDK for Android Demos (Java)
Maps SDK for Android Demos (Java)
Maps SDK for Android Demos (Kotlin)
@@ -32,12 +32,18 @@
Demonstrates how to use Camera Clamping.
Camera Clamping Demo
- Clamp to Adelaide
- Clamp to Pacific
- Reset LatLng Bounds
+ Adelaide
+ Pacific
+ Reset
+ Bounds: None
+ Bounds: Adelaide
+ Bounds: Pacific
+ Position: (%1$.6f, %2$.6f)\nzoom=%3$.1f, tilt=%4$.1f\u00b0, bearing=%5$.1f\u00b0
MinZoom++
- MaxZoom--
- Reset Zoom Bounds
+ MaxZoom--
+ Reset Zoom
+ Zoom Limits: %1$.1f – %2$.1f
+ Zoom Limits: 2.0 – 21.0
Clear
Clickable
@@ -51,6 +57,9 @@
Custom Duration
Events
Demonstrates event handling.
+ Tapped: (%1$s, %2$s)
+ Long pressed: (%1$s, %2$s)
+ Position: (%1$s, %2$s)\nzoom=%3$s, tilt=%4$s\u00b0, bearing=%5$s\u00b0
Fade In Tiles
Fill Alpha
Fill Hue
@@ -121,6 +130,9 @@
Demonstrates how to take a snapshot of the map.
Area for the map snapshot.
Take snapshot
+ Live Map
+ Captured Snapshot
+ Tap \"Take snapshot\" to capture the map
\u25A0
Stroke Alpha
Stroke Hue
@@ -199,10 +211,19 @@
Position
Demonstrates how to show a Street View panorama and map.
Street View Panorama and Map
+ Long-press & drag Pegman on the map to jump Street View. Tap arrows in Street View to walk.
+ Moved Pegman to your location
+ Finding your current location\u2026
+ Location unavailable. Please check device location settings.
+ Location permission is required to find your location. Please grant it in app settings.
Standard Street View Panorama using a Fragment.
Street View Panorama
Standard Street View Panorama with event handling.
Street View Panorama events
+ Times panorama changed=%1$d
+ Times camera changed=%1$d
+ Times clicked=%1$d : %2$s
+ Times long clicked=%1$d : %2$s
Street View Panorama with programmatic navigation.
Street View Panorama navigation
Street View Panorama with toggles for options.
@@ -217,6 +238,7 @@
Advanced Markers
Showcases the usage of Advanced Markers.
+ Hello!
DEMO_MAP_ID
diff --git a/ApiDemos/project/java-app/build.gradle.kts b/ApiDemos/project/java-app/build.gradle.kts
index 73e208bf6..ca0b55a79 100644
--- a/ApiDemos/project/java-app/build.gradle.kts
+++ b/ApiDemos/project/java-app/build.gradle.kts
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,6 +68,7 @@ dependencies {
implementation(libs.recyclerview)
implementation(libs.volley)
implementation(libs.play.services.maps)
+ implementation(libs.play.services.location)
implementation(libs.material)
implementation(libs.activity)
implementation(project(":ApiDemos:common-ui"))
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/CameraClampingDemoActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/CameraClampingDemoActivity.java
index ec2214601..44f13aff5 100644
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/CameraClampingDemoActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/CameraClampingDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -31,13 +31,13 @@
* This shows how to constrain the camera to specific boundaries and zoom levels.
*/
public class CameraClampingDemoActivity extends SamplesBaseActivity
- implements OnMapReadyCallback, OnCameraIdleListener {
+ implements OnMapReadyCallback, OnCameraIdleListener, GoogleMap.OnCameraMoveListener {
private static final String TAG = CameraClampingDemoActivity.class.getSimpleName();
private static final float ZOOM_DELTA = 2.0f;
private static final float DEFAULT_MIN_ZOOM = 2.0f;
- private static final float DEFAULT_MAX_ZOOM = 22.0f;
+ private static final float DEFAULT_MAX_ZOOM = 21.0f;
static final LatLngBounds ADELAIDE_BOUNDS = new LatLngBounds(
new LatLng(-35.0, 138.58), new LatLng(-34.9, 138.61));
@@ -71,18 +71,27 @@ protected void onCreate(Bundle savedInstanceState) {
mMap = null;
resetMinMaxZoom();
+ updateZoomLabel(mMinZoom, mMaxZoom);
+
+ binding.zoomRangeSlider.addOnChangeListener((slider, value, fromUser) -> {
+ java.util.List values = slider.getValues();
+ mMinZoom = values.get(0);
+ mMaxZoom = values.get(1);
+ updateZoomLabel(mMinZoom, mMaxZoom);
+ if (fromUser && mMap != null) {
+ mMap.setMinZoomPreference(mMinZoom);
+ mMap.setMaxZoomPreference(mMaxZoom);
+ }
+ });
binding.clampLatlngAdelaide.setOnClickListener(v -> onClampToAdelaide());
binding.clampLatlngPacific.setOnClickListener(v -> onClampToPacific());
binding.clampLatlngReset.setOnClickListener(v -> onLatLngClampReset());
- binding.clampMinZoom.setOnClickListener(v -> onSetMinZoomClamp());
- binding.clampMaxZoom.setOnClickListener(v -> onSetMaxZoomClamp());
binding.clampZoomReset.setOnClickListener(v -> onMinMaxZoomClampReset());
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(com.example.common_ui.R.id.map);
mapFragment.getMapAsync(this);
- applyInsets(binding.mapContainer);
}
@Override
@@ -93,12 +102,36 @@ protected void onResume() {
@Override
public void onMapReady(GoogleMap map) {
mMap = map;
+ map.setOnCameraMoveListener(this);
map.setOnCameraIdleListener(this);
+ updateCameraPosition();
+ }
+
+ @Override
+ public void onCameraMove() {
+ updateCameraPosition();
}
@Override
public void onCameraIdle() {
- binding.cameraText.setText(mMap.getCameraPosition().toString());
+ updateCameraPosition();
+ }
+
+ private void updateCameraPosition() {
+ if (mMap == null) return;
+ CameraPosition pos = mMap.getCameraPosition();
+ binding.cameraText.setText(getString(
+ com.example.common_ui.R.string.camera_position_format,
+ pos.target.latitude,
+ pos.target.longitude,
+ pos.zoom,
+ pos.tilt,
+ pos.bearing
+ ));
+ }
+
+ private void updateZoomLabel(float min, float max) {
+ binding.zoomLabel.setText(getString(com.example.common_ui.R.string.zoom_bounds_label, min, max));
}
/**
@@ -126,53 +159,40 @@ private void onClampToAdelaide() {
if (!checkReady()) {
return;
}
+ binding.latlngClampToggleGroup.check(com.example.common_ui.R.id.clamp_latlng_adelaide);
mMap.setLatLngBoundsForCameraTarget(ADELAIDE_BOUNDS);
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(ADELAIDE_CAMERA));
+ binding.clampStatusText.setText(getString(com.example.common_ui.R.string.latlng_clamp_status_adelaide));
}
private void onClampToPacific() {
if (!checkReady()) {
return;
}
+ binding.latlngClampToggleGroup.check(com.example.common_ui.R.id.clamp_latlng_pacific);
mMap.setLatLngBoundsForCameraTarget(PACIFIC);
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(PACIFIC_CAMERA));
+ binding.clampStatusText.setText(getString(com.example.common_ui.R.string.latlng_clamp_status_pacific));
}
private void onLatLngClampReset() {
if (!checkReady()) {
return;
}
+ binding.latlngClampToggleGroup.clearChecked();
// Setting bounds to null removes any previously set bounds.
mMap.setLatLngBoundsForCameraTarget(null);
+ binding.clampStatusText.setText(getString(com.example.common_ui.R.string.latlng_clamp_status_none));
toast("LatLngBounds clamp reset.");
}
- private void onSetMinZoomClamp() {
- if (!checkReady()) {
- return;
- }
- mMinZoom += ZOOM_DELTA;
- // Constrains the minimum zoom level.
- mMap.setMinZoomPreference(mMinZoom);
- toast("Min zoom preference set to: " + mMinZoom);
- }
-
- private void onSetMaxZoomClamp() {
- if (!checkReady()) {
- return;
- }
- mMaxZoom -= ZOOM_DELTA;
- // Constrains the maximum zoom level.
- mMap.setMaxZoomPreference(mMaxZoom);
- toast("Max zoom preference set to: " + mMaxZoom);
- }
-
private void onMinMaxZoomClampReset() {
- if (!checkReady()) {
- return;
- }
resetMinMaxZoom();
- mMap.resetMinMaxZoomPreference();
+ binding.zoomRangeSlider.setValues(DEFAULT_MIN_ZOOM, DEFAULT_MAX_ZOOM);
+ updateZoomLabel(DEFAULT_MIN_ZOOM, DEFAULT_MAX_ZOOM);
+ if (mMap != null) {
+ mMap.resetMinMaxZoomPreference();
+ }
toast("Min/Max zoom preferences reset.");
}
}
\ No newline at end of file
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/EventsDemoActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/EventsDemoActivity.java
index 6699be4ee..5114f7d36 100644
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/EventsDemoActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/EventsDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
import android.os.Bundle;
import android.widget.TextView;
+import java.util.Locale;
import androidx.appcompat.app.AppCompatActivity;
@@ -34,7 +35,7 @@
// [START maps_android_sample_events]
public class EventsDemoActivity extends SamplesBaseActivity
implements OnMapClickListener, OnMapLongClickListener, OnCameraIdleListener,
- OnMapReadyCallback {
+ GoogleMap.OnCameraMoveListener, OnMapReadyCallback {
private TextView tapTextView;
private TextView cameraTextView;
@@ -59,22 +60,51 @@ public void onMapReady(GoogleMap map) {
this.map = map;
this.map.setOnMapClickListener(this);
this.map.setOnMapLongClickListener(this);
+ this.map.setOnCameraMoveListener(this);
this.map.setOnCameraIdleListener(this);
+ updateCameraPosition();
}
@Override
public void onMapClick(LatLng point) {
- tapTextView.setText("tapped, point=" + point);
+ String lat = String.format(Locale.US, "%.6f", point.latitude);
+ String lng = String.format(Locale.US, "%.6f", point.longitude);
+ tapTextView.setText(getString(com.example.common_ui.R.string.events_tapped_format, lat, lng));
}
@Override
public void onMapLongClick(LatLng point) {
- tapTextView.setText("long pressed, point=" + point);
+ String lat = String.format(Locale.US, "%.6f", point.latitude);
+ String lng = String.format(Locale.US, "%.6f", point.longitude);
+ tapTextView.setText(getString(com.example.common_ui.R.string.events_long_pressed_format, lat, lng));
+ }
+
+ @Override
+ public void onCameraMove() {
+ updateCameraPosition();
}
@Override
public void onCameraIdle() {
- cameraTextView.setText(map.getCameraPosition().toString());
+ updateCameraPosition();
+ }
+
+ private void updateCameraPosition() {
+ if (map == null) return;
+ com.google.android.gms.maps.model.CameraPosition pos = map.getCameraPosition();
+ String lat = String.format(Locale.US, "%.6f", pos.target.latitude);
+ String lng = String.format(Locale.US, "%.6f", pos.target.longitude);
+ String zoom = String.format(Locale.US, "%.1f", pos.zoom);
+ String tilt = String.format(Locale.US, "%.1f", pos.tilt);
+ String bearing = String.format(Locale.US, "%.1f", pos.bearing);
+ cameraTextView.setText(getString(
+ com.example.common_ui.R.string.events_camera_position_format,
+ lat,
+ lng,
+ zoom,
+ tilt,
+ bearing
+ ));
}
}
// [END maps_android_sample_events]
\ No newline at end of file
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LayersDemoActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LayersDemoActivity.java
index c10f19823..259bdec86 100755
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LayersDemoActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LayersDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -88,6 +88,15 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onMapReady(GoogleMap map) {
mMap = map;
+
+ com.google.android.gms.maps.model.CameraPosition initialPosition =
+ new com.google.android.gms.maps.model.CameraPosition.Builder()
+ .target(new com.google.android.gms.maps.model.LatLng(-33.8688, 151.2093))
+ .zoom(16.5f)
+ .tilt(40.0f)
+ .build();
+ mMap.moveCamera(com.google.android.gms.maps.CameraUpdateFactory.newCameraPosition(initialPosition));
+
updateMapType();
updateTraffic();
updateMyLocation();
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LocationSourceDemoActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LocationSourceDemoActivity.java
index d3e3fd53b..e3c6e4825 100644
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LocationSourceDemoActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/LocationSourceDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -90,6 +90,11 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(com.example.common_ui.R.layout.basic_demo);
+ androidx.appcompat.widget.Toolbar toolbar = findViewById(com.example.common_ui.R.id.top_bar);
+ if (toolbar != null) {
+ toolbar.setTitle(com.example.common_ui.R.string.location_source_demo_label);
+ }
+
mLocationSource = new LongPressLocationSource();
SupportMapFragment mapFragment =
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java
index b3609b4c4..5ce1ba105 100644
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.os.SystemClock;
import com.example.common_ui.R;
@@ -429,7 +430,7 @@ public void onStopTrackingTouch(SeekBar seekBar) {
public boolean onMarkerClick(final Marker marker) {
if (marker.equals(mPerth)) {
// This causes the marker at Perth to bounce into position when it is clicked.
- final Handler handler = new Handler();
+ final Handler handler = new Handler(Looper.getMainLooper());
final long start = SystemClock.uptimeMillis();
final long duration = 1500;
@@ -485,17 +486,17 @@ public void onInfoWindowLongClick(Marker marker) {
@Override
public void onMarkerDragStart(Marker marker) {
- binding.topText.setText("onMarkerDragStart");
+ binding.topText.setText(R.string.on_marker_drag_start);
}
@Override
public void onMarkerDragEnd(Marker marker) {
- binding.topText.setText("onMarkerDragEnd");
+ binding.topText.setText(R.string.on_marker_drag_end);
}
@Override
public void onMarkerDrag(Marker marker) {
- binding.topText.setText("onMarkerDrag. Current Position: " + marker.getPosition());
+ binding.topText.setText(getString(R.string.on_marker_drag, marker.getPosition().latitude, marker.getPosition().longitude));
}
}
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/SamplesBaseActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/SamplesBaseActivity.java
index 6a1518dcb..fe9969090 100644
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/SamplesBaseActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/SamplesBaseActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2025 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
import android.os.Bundle;
import android.view.View;
+import android.view.ViewGroup;
+
import androidx.activity.EdgeToEdge;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
@@ -33,18 +35,67 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
EdgeToEdge.enable(this);
}
+ @Override
+ public void setContentView(int layoutResID) {
+ super.setContentView(layoutResID);
+ setupEdgeToEdgeInsets();
+ }
+
+ @Override
+ public void setContentView(View view) {
+ super.setContentView(view);
+ setupEdgeToEdgeInsets();
+ }
+
+ @Override
+ public void setContentView(View view, ViewGroup.LayoutParams params) {
+ super.setContentView(view, params);
+ setupEdgeToEdgeInsets();
+ }
+
+ @Override
+ public void addContentView(View view, ViewGroup.LayoutParams params) {
+ super.addContentView(view, params);
+ setupEdgeToEdgeInsets();
+ }
+
+ private void setupEdgeToEdgeInsets() {
+ View root = findViewById(android.R.id.content);
+ if (root == null) return;
+ View topBar = root.findViewById(com.example.common_ui.R.id.top_bar);
+ if (topBar != null) {
+ android.util.TypedValue typedValue = new android.util.TypedValue();
+ int baseHeight;
+ if (getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
+ baseHeight = android.util.TypedValue.complexToDimensionPixelSize(typedValue.data, getResources().getDisplayMetrics());
+ } else {
+ baseHeight = (int) (56 * getResources().getDisplayMetrics().density);
+ }
+ ViewCompat.setOnApplyWindowInsetsListener(topBar, (view, insets) -> {
+ Insets statusBar = insets.getInsets(WindowInsetsCompat.Type.statusBars() | WindowInsetsCompat.Type.displayCutout());
+ view.setPadding(statusBar.left, statusBar.top, statusBar.right, 0);
+ view.getLayoutParams().height = baseHeight + statusBar.top;
+ view.requestLayout();
+ return insets;
+ });
+ }
+
+ View mapContainer = root.findViewById(com.example.common_ui.R.id.map_container);
+ View bottomTarget = mapContainer != null ? mapContainer : root;
+ ViewCompat.setOnApplyWindowInsetsListener(bottomTarget, (view, insets) -> {
+ Insets navBars = insets.getInsets(WindowInsetsCompat.Type.navigationBars() | WindowInsetsCompat.Type.displayCutout());
+ int topInsets = (topBar == null) ? insets.getInsets(WindowInsetsCompat.Type.statusBars()).top : 0;
+ view.setPadding(navBars.left, topInsets, navBars.right, navBars.bottom);
+ return insets;
+ });
+ }
+
/**
* Applies insets to the container view to properly handle window insets.
*
* @param container the container view to apply insets to
*/
protected static void applyInsets(View container) {
- ViewCompat.setOnApplyWindowInsetsListener(container,
- (view, insets) -> {
- Insets innerPadding = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
- view.setPadding(innerPadding.left, innerPadding.top, innerPadding.right, innerPadding.bottom);
- return insets;
- }
- );
+ // Handled automatically in SamplesBaseActivity
}
}
\ No newline at end of file
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/StreetViewPanoramaEventsDemoActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/StreetViewPanoramaEventsDemoActivity.java
index ad03fb251..212217e07 100755
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/StreetViewPanoramaEventsDemoActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/StreetViewPanoramaEventsDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -98,13 +98,13 @@ protected void onCreate(final Bundle savedInstanceState) {
@Override
public void onStreetViewPanoramaChange(StreetViewPanoramaLocation location) {
if (location != null) {
- panoChangeTimesTextView.setText("Times panorama changed=" + ++panoChangeTimes);
+ panoChangeTimesTextView.setText(getString(com.example.common_ui.R.string.pano_change_times, ++panoChangeTimes));
}
}
@Override
public void onStreetViewPanoramaCameraChange(StreetViewPanoramaCamera camera) {
- panoCameraChangeTextView.setText("Times camera changed=" + ++panoCameraChangeTimes);
+ panoCameraChangeTextView.setText(getString(com.example.common_ui.R.string.pano_camera_change_times, ++panoCameraChangeTimes));
}
@Override
@@ -113,7 +113,7 @@ public void onStreetViewPanoramaClick(StreetViewPanoramaOrientation orientation)
if (point != null) {
panoClickTimes++;
panoClickTextView.setText(
- "Times clicked=" + panoClickTimes + " : " + point);
+ getString(com.example.common_ui.R.string.pano_click_times, panoClickTimes, point));
streetViewPanorama.animateTo(
new StreetViewPanoramaCamera.Builder()
.orientation(orientation)
@@ -128,7 +128,7 @@ public void onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation orientat
if (point != null) {
panoLongClickTimes++;
panoLongClickTextView.setText(
- "Times long clicked=" + panoLongClickTimes + " : " + point);
+ getString(com.example.common_ui.R.string.pano_long_click_times, panoLongClickTimes, point));
}
}
}
diff --git a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/VisibleRegionDemoActivity.java b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/VisibleRegionDemoActivity.java
index 6729049eb..bbabb704f 100755
--- a/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/VisibleRegionDemoActivity.java
+++ b/ApiDemos/project/java-app/src/main/java/com/example/mapdemo/VisibleRegionDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.os.SystemClock;
import android.view.View;
import android.view.animation.Interpolator;
@@ -89,7 +90,8 @@ public void onMapReady(GoogleMap map) {
// Add a marker to the Opera House.
mMap.addMarker(new MarkerOptions().position(SOH).title("Sydney Opera House"));
// Add a camera idle listener.
- mMap.setOnCameraIdleListener(() -> binding.messageText.setText("CameraChangeListener: " + mMap.getCameraPosition()));
+ mMap.setOnCameraIdleListener(() -> binding.messageText.setText(
+ getString(com.example.common_ui.R.string.camera_change_message, mMap.getCameraPosition())));
}
/**
@@ -147,7 +149,7 @@ public void setMorePadding(View view) {
public void animatePadding(
final int toLeft, final int toTop, final int toRight, final int toBottom) {
- final Handler handler = new Handler();
+ final Handler handler = new Handler(Looper.getMainLooper());
final long start = SystemClock.uptimeMillis();
final long duration = 1000;
diff --git a/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/MarkerDemoActivity.java b/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/MarkerDemoActivity.java
index 79c5a1f64..1a266fe08 100644
--- a/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/MarkerDemoActivity.java
+++ b/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/MarkerDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.os.SystemClock;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
@@ -435,7 +436,7 @@ public void onStopTrackingTouch(SeekBar seekBar) {
public boolean onMarkerClick(final Marker marker) {
if (marker.equals(mPerth)) {
// This causes the marker at Perth to bounce into position when it is clicked.
- final Handler handler = new Handler();
+ final Handler handler = new Handler(Looper.getMainLooper());
final long start = SystemClock.uptimeMillis();
final long duration = 1500;
@@ -491,17 +492,17 @@ public void onInfoWindowLongClick(Marker marker) {
@Override
public void onMarkerDragStart(Marker marker) {
- mTopText.setText("onMarkerDragStart");
+ mTopText.setText(com.example.common_ui.R.string.on_marker_drag_start);
}
@Override
public void onMarkerDragEnd(Marker marker) {
- mTopText.setText("onMarkerDragEnd");
+ mTopText.setText(com.example.common_ui.R.string.on_marker_drag_end);
}
@Override
public void onMarkerDrag(Marker marker) {
- mTopText.setText("onMarkerDrag. Current Position: " + marker.getPosition());
+ mTopText.setText(getString(com.example.common_ui.R.string.on_marker_drag, marker.getPosition().latitude, marker.getPosition().longitude));
}
}
diff --git a/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/VisibleRegionDemoActivity.java b/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/VisibleRegionDemoActivity.java
index 41ede6037..3e94125be 100755
--- a/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/VisibleRegionDemoActivity.java
+++ b/ApiDemos/project/java-app/src/v3/java/com/example/mapdemo/VisibleRegionDemoActivity.java
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.os.SystemClock;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
@@ -86,7 +87,8 @@ public void onMapReady(GoogleMap map) {
mMap.setOnCameraIdleListener(new OnCameraIdleListener() {
@Override
public void onCameraIdle() {
- mMessageView.setText("CameraChangeListener: " + mMap.getCameraPosition());
+ mMessageView.setText(getString(
+ com.example.common_ui.R.string.camera_change_message, mMap.getCameraPosition()));
}
});
}
@@ -146,7 +148,7 @@ public void setMorePadding(View view) {
public void animatePadding(
final int toLeft, final int toTop, final int toRight, final int toBottom) {
- final Handler handler = new Handler();
+ final Handler handler = new Handler(Looper.getMainLooper());
final long start = SystemClock.uptimeMillis();
final long duration = 1000;
diff --git a/ApiDemos/project/kotlin-app/build.gradle.kts b/ApiDemos/project/kotlin-app/build.gradle.kts
index 810fa6e18..868ca5bf6 100644
--- a/ApiDemos/project/kotlin-app/build.gradle.kts
+++ b/ApiDemos/project/kotlin-app/build.gradle.kts
@@ -1,7 +1,7 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
/*
- * Copyright 2025 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ android {
buildTypes {
getByName("release") {
isMinifyEnabled = true
+ isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
@@ -84,6 +85,7 @@ dependencies {
implementation(libs.lifecycle.runtime.ktx)
implementation(libs.maps.ktx)
implementation(libs.maps.utils.ktx)
+ implementation(libs.play.services.location)
implementation(libs.activity)
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationDemoActivity.kt
index 417051e6e..1e8e59297 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ class BackgroundColorCustomizationDemoActivity : SamplesBaseActivity(), OnMapRea
setContentView(R.layout.background_color_customization_demo)
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(this)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
/**
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationProgrammaticDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationProgrammaticDemoActivity.kt
index 11d39d4da..a7fff2c83 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationProgrammaticDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/BackgroundColorCustomizationProgrammaticDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2021 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ class BackgroundColorCustomizationProgrammaticDemoActivity : SamplesBaseActivity
} else {
mapFragment.getMapAsync(this)
}
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onMapReady(map: GoogleMap) {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CameraClampingDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CameraClampingDemoActivity.kt
index 061b2b126..e55bca42c 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CameraClampingDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CameraClampingDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -42,10 +42,6 @@ class CameraClampingDemoActivity : SamplesBaseActivity() {
* Internal min zoom level that can be toggled via the demo.
*/
private var minZoom = DEFAULT_MIN_ZOOM
-
- /**
- * Internal max zoom level that can be toggled via the demo.
- */
private var maxZoom = DEFAULT_MAX_ZOOM
@OptIn(ExperimentalCoroutinesApi::class)
@@ -53,59 +49,80 @@ class CameraClampingDemoActivity : SamplesBaseActivity() {
super.onCreate(savedInstanceState)
binding = com.example.common_ui.databinding.CameraClampingDemoBinding.inflate(layoutInflater)
setContentView(binding.root)
+ updateZoomLabel(minZoom, maxZoom)
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
- lifecycleScope.launchWhenCreated {
+ lifecycleScope.launch {
map = mapFragment.awaitMap()
- launch {
- map.cameraIdleEvents().collect {
- onCameraIdle()
- }
+ updateCameraPosition()
+ map.setOnCameraMoveListener {
+ updateCameraPosition()
}
- setButtonClickListeners()
+ map.setOnCameraIdleListener {
+ updateCameraPosition()
+ }
+ setControls()
}
- applyInsets(binding.mapContainer)
}
- private fun setButtonClickListeners() {
-
- binding.clampMinZoom.setOnClickListener {
- minZoom += ZOOM_DELTA
- // Constrains the minimum zoom level.
- map.setMinZoomPreference(minZoom)
- toast("Min zoom preference set to: $minZoom")
- }
-
- binding.clampMaxZoom.setOnClickListener {
- maxZoom -= ZOOM_DELTA
- // Constrains the maximum zoom level.
- map.setMaxZoomPreference(maxZoom)
- toast("Max zoom preference set to: $maxZoom")
+ private fun setControls() {
+ binding.zoomRangeSlider.addOnChangeListener { slider, _, fromUser ->
+ val values = slider.values
+ minZoom = values[0]
+ maxZoom = values[1]
+ updateZoomLabel(minZoom, maxZoom)
+ if (fromUser && ::map.isInitialized) {
+ map.setMinZoomPreference(minZoom)
+ map.setMaxZoomPreference(maxZoom)
+ }
}
binding.clampZoomReset.setOnClickListener {
resetMinMaxZoom()
- map.resetMinMaxZoomPreference()
+ binding.zoomRangeSlider.setValues(DEFAULT_MIN_ZOOM, DEFAULT_MAX_ZOOM)
+ updateZoomLabel(DEFAULT_MIN_ZOOM, DEFAULT_MAX_ZOOM)
+ if (::map.isInitialized) {
+ map.resetMinMaxZoomPreference()
+ }
toast("Min/Max zoom preferences reset.")
}
binding.clampLatlngAdelaide.setOnClickListener {
+ binding.latlngClampToggleGroup.check(R.id.clamp_latlng_adelaide)
map.setLatLngBoundsForCameraTarget(ADELAIDE_BOUNDS)
map.animateCamera(CameraUpdateFactory.newCameraPosition(ADELAIDE_CAMERA))
+ binding.clampStatusText.text = getString(R.string.latlng_clamp_status_adelaide)
}
binding.clampLatlngPacific.setOnClickListener {
+ binding.latlngClampToggleGroup.check(R.id.clamp_latlng_pacific)
map.setLatLngBoundsForCameraTarget(PACIFIC)
map.animateCamera(CameraUpdateFactory.newCameraPosition(PACIFIC_CAMERA))
+ binding.clampStatusText.text = getString(R.string.latlng_clamp_status_pacific)
}
binding.clampLatlngReset.setOnClickListener {
+ binding.latlngClampToggleGroup.clearChecked()
map.setLatLngBoundsForCameraTarget(null)
+ binding.clampStatusText.text = getString(R.string.latlng_clamp_status_none)
toast("LatLngBounds clamp reset.")
}
}
- private fun onCameraIdle() {
- binding.cameraText.text = map.cameraPosition.toString()
+ private fun updateZoomLabel(min: Float, max: Float) {
+ binding.zoomLabel.text = getString(R.string.zoom_bounds_label, min, max)
+ }
+
+ private fun updateCameraPosition() {
+ if (!::map.isInitialized) return
+ val pos = map.cameraPosition
+ binding.cameraText.text = getString(
+ R.string.camera_position_format,
+ pos.target.latitude,
+ pos.target.longitude,
+ pos.zoom,
+ pos.tilt,
+ pos.bearing
+ )
}
private fun toast(msg: String) {
@@ -121,7 +138,7 @@ class CameraClampingDemoActivity : SamplesBaseActivity() {
private val TAG = CameraClampingDemoActivity::class.java.name
private const val ZOOM_DELTA = 2.0f
private const val DEFAULT_MIN_ZOOM = 2.0f
- private const val DEFAULT_MAX_ZOOM = 22.0f
+ private const val DEFAULT_MAX_ZOOM = 21.0f
val ADELAIDE_BOUNDS = LatLngBounds(
LatLng(-35.0, 138.58), LatLng(-34.9, 138.61))
private val ADELAIDE_CAMERA = CameraPosition.Builder()
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CloudBasedMapStylingDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CloudBasedMapStylingDemoActivity.kt
index 3622e4cd3..8dc6e5983 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CloudBasedMapStylingDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/CloudBasedMapStylingDemoActivity.kt
@@ -6,7 +6,7 @@
* corresponding file under the `app/src/gms` directory.
*/
/*
- * Copyright 2020 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@ class CloudBasedMapStylingDemoActivity : SamplesBaseActivity(), OnMapReadyCallba
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment!!.getMapAsync(this)
setUpButtonListeners()
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onMapReady(map: GoogleMap) {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/DataDrivenBoundariesActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/DataDrivenBoundariesActivity.kt
index 26d0c7d82..c80f5ab51 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/DataDrivenBoundariesActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/DataDrivenBoundariesActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2025 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -107,7 +107,7 @@ class DataDrivenBoundariesActivity : SamplesBaseActivity(), OnMapReadyCallback,
setupBoundarySelectorButton() // Setup the new selector button
// --- Insets ---
- applyInsets(findViewById(R.id.map_container)) // Apply insets if needed
+ applyInsets(findViewById(R.id.map_container)) // Apply insets if needed
}
private fun setupBoundarySelectorButton() {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/EventsDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/EventsDemoActivity.kt
index 384eba27a..1658f11ad 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/EventsDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/EventsDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ import android.os.Bundle
import android.view.View
import android.widget.TextView
import com.example.common_ui.R
+import java.util.Locale
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.GoogleMap.*
@@ -29,7 +30,7 @@ import com.google.android.gms.maps.model.LatLng
*/
// [START maps_android_sample_events]
class EventsDemoActivity : SamplesBaseActivity(), OnMapClickListener,
- OnMapLongClickListener, OnCameraIdleListener, OnMapReadyCallback {
+ OnMapLongClickListener, OnCameraIdleListener, OnCameraMoveListener, OnMapReadyCallback {
private lateinit var tapTextView: TextView
private lateinit var cameraTextView: TextView
@@ -42,28 +43,47 @@ class EventsDemoActivity : SamplesBaseActivity(), OnMapClickListener,
cameraTextView = findViewById(R.id.camera_text)
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(this)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onMapReady(googleMap: GoogleMap) {
- // return early if the map was not initialised properly
map = googleMap
map.setOnMapClickListener(this)
map.setOnMapLongClickListener(this)
+ map.setOnCameraMoveListener(this)
map.setOnCameraIdleListener(this)
+ updateCameraPosition()
}
override fun onMapClick(point: LatLng) {
- tapTextView.text = "tapped, point=$point"
+ val lat = String.format(Locale.US, "%.6f", point.latitude)
+ val lng = String.format(Locale.US, "%.6f", point.longitude)
+ tapTextView.text = getString(R.string.events_tapped_format, lat, lng)
}
override fun onMapLongClick(point: LatLng) {
- tapTextView.text = "long pressed, point=$point"
+ val lat = String.format(Locale.US, "%.6f", point.latitude)
+ val lng = String.format(Locale.US, "%.6f", point.longitude)
+ tapTextView.text = getString(R.string.events_long_pressed_format, lat, lng)
+ }
+
+ override fun onCameraMove() {
+ updateCameraPosition()
}
override fun onCameraIdle() {
+ updateCameraPosition()
+ }
+
+ private fun updateCameraPosition() {
if (!::map.isInitialized) return
- cameraTextView.text = map.cameraPosition.toString()
+ val pos = map.cameraPosition
+ val lat = String.format(Locale.US, "%.6f", pos.target.latitude)
+ val lng = String.format(Locale.US, "%.6f", pos.target.longitude)
+ val zoom = String.format(Locale.US, "%.1f", pos.zoom)
+ val tilt = String.format(Locale.US, "%.1f", pos.tilt)
+ val bearing = String.format(Locale.US, "%.1f", pos.bearing)
+ cameraTextView.text = getString(R.string.events_camera_position_format, lat, lng, zoom, tilt, bearing)
}
}
// [END maps_android_sample_events]
\ No newline at end of file
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LayersDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LayersDemoActivity.kt
index 42167e088..35d2c64fe 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LayersDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LayersDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import android.widget.CheckBox
import android.widget.Spinner
import com.example.common_ui.R
+import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.GoogleMap.MAP_TYPE_HYBRID
import com.google.android.gms.maps.GoogleMap.MAP_TYPE_NONE
@@ -36,6 +37,8 @@ import com.google.android.gms.maps.GoogleMap.MAP_TYPE_SATELLITE
import com.google.android.gms.maps.GoogleMap.MAP_TYPE_TERRAIN
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
+import com.google.android.gms.maps.model.CameraPosition
+import com.google.android.gms.maps.model.LatLng
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
@@ -106,6 +109,13 @@ class LayersDemoActivity :
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
+ val initialPosition = CameraPosition.builder()
+ .target(LatLng(-33.8688, 151.2093))
+ .zoom(16.5f)
+ .tilt(40.0f)
+ .build()
+ map.moveCamera(CameraUpdateFactory.newCameraPosition(initialPosition))
+
updateMapType()
// check the state of all checkboxes and update the map accordingly
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LocationSourceDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LocationSourceDemoActivity.kt
index 21fad59e8..55cb9d63f 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LocationSourceDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/LocationSourceDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21,9 +21,8 @@ import android.os.Bundle
import android.view.View
import androidx.core.app.ActivityCompat
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleObserver
-import androidx.lifecycle.OnLifecycleEvent
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.example.common_ui.R
import com.google.android.gms.maps.GoogleMap
@@ -34,6 +33,8 @@ import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.ktx.awaitMap
+import kotlinx.coroutines.launch
+
/**
* This shows how to use a custom location source.
*/
@@ -44,13 +45,14 @@ class LocationSourceDemoActivity : SamplesBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.basic_demo)
+ findViewById(R.id.top_bar)?.setTitle(R.string.location_source_demo_label)
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
- lifecycleScope.launchWhenCreated {
+ lifecycleScope.launch {
val map = mapFragment.awaitMap()
init(map = map)
}
lifecycle.addObserver(locationSource)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
@SuppressLint("MissingPermission")
@@ -72,7 +74,7 @@ class LocationSourceDemoActivity : SamplesBaseActivity() {
* at
* the point at which a user long pressed the map.
*/
-private class LongPressLocationSource : LocationSource, OnMapLongClickListener, LifecycleObserver {
+private class LongPressLocationSource : LocationSource, OnMapLongClickListener, DefaultLifecycleObserver {
private var listener: OnLocationChangedListener? = null
@@ -104,13 +106,11 @@ private class LongPressLocationSource : LocationSource, OnMapLongClickListener,
listener?.onLocationChanged(location)
}
- @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
- fun onPause() {
+ override fun onPause(owner: LifecycleOwner) {
paused = true
}
- @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
- fun onResume() {
+ override fun onResume(owner: LifecycleOwner) {
paused = false
}
}
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapColorSchemeActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapColorSchemeActivity.kt
index a2866b03e..460f4cbbf 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapColorSchemeActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapColorSchemeActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2025 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ class MapColorSchemeActivity :
buttonLight = findViewById(R.id.map_color_light_mode)
buttonDark = findViewById(R.id.map_color_dark_mode)
buttonFollowSystem = findViewById(R.id.map_color_follow_system_mode)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onMapReady(googleMap: GoogleMap) {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapInPagerDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapInPagerDemoActivity.kt
index eff3890bf..edeb7f36e 100755
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapInPagerDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MapInPagerDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ class MapInPagerDemoActivity : SamplesBaseActivity() {
// This is required to avoid a black flash when the map is loaded. The flash is due
// to the use of a SurfaceView as the underlying view of the map.
pager.requestTransparentRegion(pager)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
/** A simple fragment that displays a TextView. */
@@ -55,6 +55,7 @@ class MapInPagerDemoActivity : SamplesBaseActivity() {
}
/** A simple FragmentPagerAdapter that returns two TextFragment and a SupportMapFragment. */
+ @Suppress("DEPRECATION")
class MyAdapter(fm: FragmentManager) :
FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerCloseInfoWindowOnRetapDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerCloseInfoWindowOnRetapDemoActivity.kt
index c9397e4e0..c37dab971 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerCloseInfoWindowOnRetapDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerCloseInfoWindowOnRetapDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,7 +70,7 @@ class MarkerCloseInfoWindowOnRetapDemoActivity :
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
OnMapAndViewReadyListener(mapFragment, this)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onMapReady(googleMap: GoogleMap?) {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerDemoActivity.kt
index ce22a382e..61915601f 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MarkerDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Handler
+import android.os.Looper
import android.os.SystemClock
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
@@ -36,7 +37,9 @@ import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.core.content.res.ResourcesCompat
+import androidx.core.graphics.createBitmap
import androidx.core.graphics.drawable.DrawableCompat
+import androidx.core.graphics.toColorInt
import com.example.common_ui.R
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
@@ -290,7 +293,7 @@ class MarkerDemoActivity :
position = places.getValue("ALICE_SPRINGS"),
title = "Alice Springs",
icon = vectorToBitmap(
- R.drawable.ic_android, Color.parseColor("#A4C639"))
+ R.drawable.ic_android, "#A4C639".toColorInt())
),
// More markers for good measure
@@ -363,8 +366,11 @@ class MarkerDemoActivity :
Log.e(TAG, "Resource not found")
return BitmapDescriptorFactory.defaultMarker()
}
- val bitmap = Bitmap.createBitmap(vectorDrawable.intrinsicWidth,
- vectorDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
+ val 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)
@@ -401,7 +407,7 @@ class MarkerDemoActivity :
if (marker.position == places.getValue("PERTH")) {
// This causes the marker at Perth to bounce into position when it is clicked.
- val handler = Handler()
+ val handler = Handler(Looper.getMainLooper())
val start = SystemClock.uptimeMillis()
val duration = 1500
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MultiMapDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MultiMapDemoActivity.kt
index 1ca406943..6beb36268 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MultiMapDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MultiMapDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -25,6 +25,6 @@ class MultiMapDemoActivity : SamplesBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.multimap_demo)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
}
\ No newline at end of file
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MyLocationDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MyLocationDemoActivity.kt
index e86d74bff..65ce1558a 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MyLocationDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/MyLocationDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -56,7 +56,7 @@ class MyLocationDemoActivity : SamplesBaseActivity(),
val mapFragment =
supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
mapFragment?.getMapAsync(this)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onMapReady(googleMap: GoogleMap) {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt
index 58f018c46..ad6ec6b43 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ class OnMapAndViewReadyListener(
) : OnGlobalLayoutListener,
OnMapReadyCallback {
- private val mapView: View? = mapFragment.view
+ private var mapView: View? = null
private var isViewReady = false
private var isMapReady = false
@@ -52,16 +52,6 @@ class OnMapAndViewReadyListener(
}
private fun registerListeners() {
- // View layout.
- mapView?.let {
- if (it.width != 0 && it.height != 0) {
- // View has already completed layout.
- isViewReady = true
- } else {
- // Map has not undergone layout, register a View observer.
- it.viewTreeObserver.addOnGlobalLayoutListener(this)
- }
- }
// GoogleMap. Note if the GoogleMap is already ready it will still fire the callback later.
mapFragment.getMapAsync(this)
}
@@ -70,6 +60,22 @@ class OnMapAndViewReadyListener(
// NOTE: The GoogleMap API specifies the listener is removed just prior to invocation.
map = googleMap
isMapReady = true
+
+ // View layout.
+ mapView = mapFragment.view
+ val view = mapView
+ if (view != null) {
+ if (view.width != 0 && view.height != 0) {
+ // View has already completed layout.
+ isViewReady = true
+ } else {
+ // Map has not undergone layout, register a View observer.
+ view.viewTreeObserver.addOnGlobalLayoutListener(this)
+ }
+ } else {
+ isViewReady = true
+ }
+
fireCallbackIfReady()
}
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolygonDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolygonDemoActivity.kt
index fea47f8b7..71a236a39 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolygonDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolygonDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -131,7 +131,7 @@ class PolygonDemoActivity :
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
// [START_EXCLUDE silent]
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolylineDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolylineDemoActivity.kt
index a871551ea..e0c8f7b03 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolylineDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/PolylineDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -155,7 +155,7 @@ class PolylineDemoActivity :
val mapFragment = supportFragmentManager.findFragmentById(com.example.common_ui.R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
- applyInsets(findViewById(com.example.common_ui.R.id.map_container))
+ applyInsets(findViewById(com.example.common_ui.R.id.map_container))
}
// [START_EXCLUDE silent]
@@ -165,8 +165,6 @@ class PolylineDemoActivity :
// [END_EXCLUDE]
override fun onMapReady(googleMap: GoogleMap) {
- googleMap
-
with(googleMap) {
// Override the default content description on the view, for accessibility mode.
setContentDescription(getString(com.example.common_ui.R.string.polyline_demo_description))
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/ProgrammaticDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/ProgrammaticDemoActivity.kt
index b54d13098..fdb4f236a 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/ProgrammaticDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/ProgrammaticDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2025 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
// limitations under the License.
package com.example.kotlindemos
-import android.R
import android.os.Bundle
import android.view.View
import androidx.lifecycle.lifecycleScope
@@ -21,6 +20,7 @@ import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.ktx.addMarker
import com.google.maps.android.ktx.awaitMap
+import kotlinx.coroutines.launch
/**
* Demonstrates how to instantiate a SupportMapFragment programmatically and add a marker to it.
@@ -36,18 +36,18 @@ class ProgrammaticDemoActivity : SamplesBaseActivity() {
?: SupportMapFragment.newInstance().also {
// Then we add it using a FragmentTransaction.
val fragmentTransaction = supportFragmentManager.beginTransaction()
- fragmentTransaction.add(R.id.content, it, MAP_FRAGMENT_TAG)
+ fragmentTransaction.add(android.R.id.content, it, MAP_FRAGMENT_TAG)
fragmentTransaction.commit()
}
- lifecycleScope.launchWhenCreated {
+ lifecycleScope.launch {
val map = mapFragment.awaitMap()
map.addMarker {
position(LatLng(0.0, 0.0))
title("Marker")
}
}
- applyInsets(findViewById(com.example.common_ui.R.id.map_container))
+ applyInsets(findViewById(com.example.common_ui.R.id.map_container))
}
companion object {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/RetainMapDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/RetainMapDemoActivity.kt
index 36c22497f..f837e601c 100755
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/RetainMapDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/RetainMapDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.ktx.addMarker
import com.google.maps.android.ktx.awaitMap
+import kotlinx.coroutines.launch
/**
* This shows how to retain a map across activity restarts (e.g., from screen rotations), which can
@@ -34,15 +35,16 @@ class RetainMapDemoActivity : SamplesBaseActivity() {
supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
if (savedInstanceState == null) {
// First incarnation of this activity.
+ @Suppress("DEPRECATION")
mapFragment.retainInstance = true
}
- lifecycleScope.launchWhenCreated {
+ lifecycleScope.launch {
val map = mapFragment.awaitMap()
map.addMarker {
position(LatLng(0.0, 0.0))
title("Marker")
}
}
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
}
\ No newline at end of file
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SamplesBaseActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SamplesBaseActivity.kt
index a6982e167..e9d9d2ecf 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SamplesBaseActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SamplesBaseActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2025 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,9 +15,9 @@ package com.example.kotlindemos
import android.os.Bundle
import android.view.View
+import android.view.ViewGroup
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
@@ -27,27 +27,81 @@ open class SamplesBaseActivity : AppCompatActivity() {
enableEdgeToEdge()
}
+ override fun setContentView(layoutResID: Int) {
+ super.setContentView(layoutResID)
+ setupEdgeToEdgeInsets()
+ }
+
+ override fun setContentView(view: View?) {
+ super.setContentView(view)
+ setupEdgeToEdgeInsets()
+ }
+
+ override fun setContentView(view: View?, params: ViewGroup.LayoutParams?) {
+ super.setContentView(view, params)
+ setupEdgeToEdgeInsets()
+ }
+
+ override fun addContentView(view: View?, params: ViewGroup.LayoutParams?) {
+ super.addContentView(view, params)
+ setupEdgeToEdgeInsets()
+ }
+
+ private fun setupEdgeToEdgeInsets() {
+ val root = findViewById(android.R.id.content) ?: return
+ val topBar = root.findViewById(com.example.common_ui.R.id.top_bar)
+ if (topBar != null) {
+ val typedValue = android.util.TypedValue()
+ val baseHeight = if (theme.resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
+ android.util.TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics)
+ } else {
+ (56 * resources.displayMetrics.density).toInt()
+ }
+ ViewCompat.setOnApplyWindowInsetsListener(topBar) { view, insets ->
+ val statusBar = insets.getInsets(
+ WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.displayCutout()
+ )
+ view.setPadding(
+ statusBar.left,
+ statusBar.top,
+ statusBar.right,
+ 0
+ )
+ view.layoutParams.height = baseHeight + statusBar.top
+ view.requestLayout()
+ insets
+ }
+ }
+
+ val mapContainer = root.findViewById(com.example.common_ui.R.id.map_container)
+ val bottomTarget = mapContainer ?: root
+ ViewCompat.setOnApplyWindowInsetsListener(bottomTarget) { view, insets ->
+ val navBars = insets.getInsets(
+ WindowInsetsCompat.Type.navigationBars() or WindowInsetsCompat.Type.displayCutout()
+ )
+ val topInsets = if (topBar == null) {
+ insets.getInsets(WindowInsetsCompat.Type.statusBars()).top
+ } else {
+ 0
+ }
+ view.setPadding(
+ navBars.left,
+ topInsets,
+ navBars.right,
+ navBars.bottom
+ )
+ insets
+ }
+ }
+
companion object {
/**
* Applies insets to the container view to properly handle window insets.
*
* @param container the container view to apply insets to
*/
- fun applyInsets(container: View) {
- ViewCompat.setOnApplyWindowInsetsListener(
- container,
- OnApplyWindowInsetsListener { view: View?, insets: WindowInsetsCompat? ->
- val innerPadding =
- insets!!.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
- view!!.setPadding(
- innerPadding.left,
- innerPadding.top,
- innerPadding.right,
- innerPadding.bottom
- )
- insets
- }
- )
+ fun applyInsets(container: View? = null) {
+ // Handled automatically in SamplesBaseActivity
}
}
}
\ No newline at end of file
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SaveStateDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SaveStateDemoActivity.kt
index 07cbd9110..a9b116003 100755
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SaveStateDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/SaveStateDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ package com.example.kotlindemos
import android.os.Bundle
import android.os.Parcelable
+import androidx.core.os.BundleCompat
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener
@@ -26,7 +27,8 @@ import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.maps.android.ktx.addMarker
import com.google.maps.android.ktx.awaitMap
-import kotlinx.android.parcel.Parcelize
+import kotlinx.parcelize.Parcelize
+import kotlinx.coroutines.launch
import java.util.Random
/**
@@ -73,13 +75,15 @@ class SaveStateDemoActivity : SamplesBaseActivity() {
// the savedInsanceState Bundle.
// - Custom Parcelable objects were wrapped in another Bundle.
mMarkerPosition =
- savedInstanceState?.getParcelable(MARKER_POSITION) ?: DEFAULT_MARKER_POSITION
+ savedInstanceState?.let { BundleCompat.getParcelable(it, MARKER_POSITION, LatLng::class.java) }
+ ?: DEFAULT_MARKER_POSITION
mMarkerInfo =
- savedInstanceState?.getBundle(OTHER_OPTIONS)?.getParcelable(MARKER_INFO) ?: MarkerInfo(
- BitmapDescriptorFactory.HUE_RED)
+ savedInstanceState?.getBundle(OTHER_OPTIONS)?.let {
+ BundleCompat.getParcelable(it, MARKER_INFO, MarkerInfo::class.java)
+ } ?: MarkerInfo(BitmapDescriptorFactory.HUE_RED)
mMoveCameraToMarker = savedInstanceState == null
- lifecycleScope.launchWhenCreated {
+ lifecycleScope.launch {
val map = awaitMap()
map.addMarker {
icon(BitmapDescriptorFactory.defaultMarker(mMarkerInfo.hue))
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaBasicDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaBasicDemoActivity.kt
index 40ea537b1..bc1c68d5a 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaBasicDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaBasicDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ class StreetViewPanoramaBasicDemoActivity : SamplesBaseActivity() {
// loaded which is when the savedInstanceState is null).
savedInstanceState ?: panorama.setPosition(SYDNEY)
}
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
companion object {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaEventsDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaEventsDemoActivity.kt
index 1930d9fa7..37bdf0f3d 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaEventsDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaEventsDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -74,22 +74,22 @@ class StreetViewPanoramaEventsDemoActivity : SamplesBaseActivity(),
// loaded which is when the savedInstanceState is null).
savedInstanceState ?: streetViewPanorama.setPosition(SYDNEY)
}
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onStreetViewPanoramaChange(location: StreetViewPanoramaLocation) {
- panoChangeTimesTextView.text = "Times panorama changed=" + ++panoChangeTimes
+ panoChangeTimesTextView.text = getString(R.string.pano_change_times, ++panoChangeTimes)
}
override fun onStreetViewPanoramaCameraChange(camera: StreetViewPanoramaCamera) {
- panoCameraChangeTextView.text = "Times camera changed=" + ++panoCameraChangeTimes
+ panoCameraChangeTextView.text = getString(R.string.pano_camera_change_times, ++panoCameraChangeTimes)
}
override fun onStreetViewPanoramaClick(orientation: StreetViewPanoramaOrientation) {
val point = streetViewPanorama.orientationToPoint(orientation)
point?.let {
panoClickTimes++
- panoClickTextView.text = "Times clicked=$panoClickTimes : $point"
+ panoClickTextView.text = getString(R.string.pano_click_times, panoClickTimes, it)
streetViewPanorama.animateTo(
StreetViewPanoramaCamera.Builder()
.orientation(orientation)
@@ -103,7 +103,7 @@ class StreetViewPanoramaEventsDemoActivity : SamplesBaseActivity(),
val point = streetViewPanorama.orientationToPoint(orientation)
if (point != null) {
panoLongClickTimes++
- panoLongClickTextView.text = "Times long clicked=$panoLongClickTimes : $point"
+ panoLongClickTextView.text = getString(R.string.pano_long_click_times, panoLongClickTimes, point)
}
}
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaNavigationDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaNavigationDemoActivity.kt
index e06169426..a08b1b111 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaNavigationDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaNavigationDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -190,7 +190,7 @@ class StreetViewPanoramaNavigationDemoActivity : SamplesBaseActivity() {
private fun onMovePosition() {
val location = streetViewPanorama.location
val camera = streetViewPanorama.panoramaCamera
- location.links?.let {
+ if (location.links.isNotEmpty()) {
val link = location.links.findClosestLinkToBearing(camera.bearing)
streetViewPanorama.setPosition(link.panoId)
}
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaViewDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaViewDemoActivity.kt
index 296844220..b427adad5 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaViewDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StreetViewPanoramaViewDemoActivity.kt
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@ class StreetViewPanoramaViewDemoActivity : SamplesBaseActivity() {
// StreetViewPanoramaView requires that the Bundle you pass contain _ONLY_
// StreetViewPanoramaView SDK objects or sub-Bundles.
streetViewPanoramaView.onCreate(savedInstanceState?.getBundle(STREETVIEW_BUNDLE_KEY))
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onResume() {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StyledMapDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StyledMapDemoActivity.kt
index 7df53b8fc..7c638b8e3 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StyledMapDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/StyledMapDemoActivity.kt
@@ -1,148 +1,148 @@
-/*
- * Copyright 2023 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.content.DialogInterface
-import android.os.Bundle
-import android.util.Log
-import android.view.Menu
-import android.view.MenuItem
-import android.view.View
-import android.widget.Toast
-import androidx.appcompat.app.AlertDialog
-
-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.LatLng
-import com.google.android.gms.maps.model.MapStyleOptions
-import java.util.ArrayList
-
-class StyledMapDemoActivity : SamplesBaseActivity(), OnMapReadyCallback {
-
- private var mMap: GoogleMap? = null
- private var mSelectedStyleId = com.example.common_ui.R.string.style_label_default
-
- companion object {
- private const val TAG = "StyledMapDemoActivity"
- private const val SELECTED_STYLE = "selected_style"
- private val SYDNEY = LatLng(-33.8688, 151.2093)
- }
-
- private val mStyleIds = intArrayOf(
- com.example.common_ui.R.string.style_label_retro,
- com.example.common_ui.R.string.style_label_night,
- com.example.common_ui.R.string.style_label_grayscale,
- com.example.common_ui.R.string.style_label_no_pois_no_transit,
- com.example.common_ui.R.string.style_label_default
- )
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- if (savedInstanceState != null) {
- mSelectedStyleId = savedInstanceState.getInt(SELECTED_STYLE)
- }
- setContentView(com.example.common_ui.R.layout.styled_map_demo)
-
- val mapFragment =
- supportFragmentManager.findFragmentById(com.example.common_ui.R.id.map) as SupportMapFragment
- mapFragment.getMapAsync(this)
- applyInsets(findViewById(com.example.common_ui.R.id.map_container))
- }
-
- override fun onSaveInstanceState(outState: Bundle) {
- outState.putInt(SELECTED_STYLE, mSelectedStyleId)
- super.onSaveInstanceState(outState)
- }
-
- override fun onMapReady(map: GoogleMap) {
- mMap = map
- mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 14f))
- setSelectedStyle()
- }
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- menuInflater.inflate(R.menu.styled_map, menu)
- return true
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == com.example.common_ui.R.id.menu_style_choose) {
- showStylesDialog()
- }
- return true
- }
-
- private fun showStylesDialog() {
- val styleNames = ArrayList()
- for (style in mStyleIds) {
- styleNames.add(getString(style))
- }
-
- val builder = AlertDialog.Builder(this)
- builder.setTitle(getString(com.example.common_ui.R.string.style_choose))
- builder.setItems(styleNames.toTypedArray(),
- DialogInterface.OnClickListener { _, which ->
- mSelectedStyleId = mStyleIds[which]
- val msg = getString(com.example.common_ui.R.string.style_set_to, getString(mSelectedStyleId))
- Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
- Log.d(TAG, msg)
- setSelectedStyle()
- })
- builder.show()
- }
-
- private fun setSelectedStyle() {
- val style: MapStyleOptions?
- val id = mSelectedStyleId
- style = when (id) {
- com.example.common_ui.R.string.style_label_retro ->
- MapStyleOptions.loadRawResourceStyle(this, com.example.common_ui.R.raw.mapstyle_retro)
- com.example.common_ui.R.string.style_label_night ->
- MapStyleOptions.loadRawResourceStyle(this, com.example.common_ui.R.raw.mapstyle_night)
- com.example.common_ui.R.string.style_label_grayscale ->
- MapStyleOptions.loadRawResourceStyle(this, com.example.common_ui.R.raw.mapstyle_grayscale)
- com.example.common_ui.R.string.style_label_no_pois_no_transit ->
- MapStyleOptions(
- "[" +
- " {" +
- " \"featureType\":\"poi.business\"," +
- " \"elementType\":\"all\"," +
- " \"stylers\":[" +
- " {" +
- " \"visibility\":\"off\"" +
- " }" +
- " ]" +
- " }," +
- " {" +
- " \"featureType\":\"transit\"," +
- " \"elementType\":\"all\"," +
- " \"stylers\":[" +
- " {" +
- " \"visibility\":\"off\"" +
- " }" +
- " ]" +
- " }" +
- "]"
- )
- com.example.common_ui.R.string.style_label_default -> null
- else -> return
- }
- mMap?.setMapStyle(style)
- }
-}
+/*
+ * Copyright 2026 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.content.DialogInterface
+import android.os.Bundle
+import android.util.Log
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.widget.Toast
+import androidx.appcompat.app.AlertDialog
+
+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.LatLng
+import com.google.android.gms.maps.model.MapStyleOptions
+import java.util.ArrayList
+
+class StyledMapDemoActivity : SamplesBaseActivity(), OnMapReadyCallback {
+
+ private var mMap: GoogleMap? = null
+ private var mSelectedStyleId = com.example.common_ui.R.string.style_label_default
+
+ companion object {
+ private const val TAG = "StyledMapDemoActivity"
+ private const val SELECTED_STYLE = "selected_style"
+ private val SYDNEY = LatLng(-33.8688, 151.2093)
+ }
+
+ private val mStyleIds = intArrayOf(
+ com.example.common_ui.R.string.style_label_retro,
+ com.example.common_ui.R.string.style_label_night,
+ com.example.common_ui.R.string.style_label_grayscale,
+ com.example.common_ui.R.string.style_label_no_pois_no_transit,
+ com.example.common_ui.R.string.style_label_default
+ )
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ if (savedInstanceState != null) {
+ mSelectedStyleId = savedInstanceState.getInt(SELECTED_STYLE)
+ }
+ setContentView(com.example.common_ui.R.layout.styled_map_demo)
+
+ val mapFragment =
+ supportFragmentManager.findFragmentById(com.example.common_ui.R.id.map) as SupportMapFragment
+ mapFragment.getMapAsync(this)
+ applyInsets(findViewById(com.example.common_ui.R.id.map_container))
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ outState.putInt(SELECTED_STYLE, mSelectedStyleId)
+ super.onSaveInstanceState(outState)
+ }
+
+ override fun onMapReady(map: GoogleMap) {
+ mMap = map
+ mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 14f))
+ setSelectedStyle()
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.styled_map, menu)
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == com.example.common_ui.R.id.menu_style_choose) {
+ showStylesDialog()
+ }
+ return true
+ }
+
+ private fun showStylesDialog() {
+ val styleNames = ArrayList()
+ for (style in mStyleIds) {
+ styleNames.add(getString(style))
+ }
+
+ val builder = AlertDialog.Builder(this)
+ builder.setTitle(getString(com.example.common_ui.R.string.style_choose))
+ builder.setItems(styleNames.toTypedArray(),
+ DialogInterface.OnClickListener { _, which ->
+ mSelectedStyleId = mStyleIds[which]
+ val msg = getString(com.example.common_ui.R.string.style_set_to, getString(mSelectedStyleId))
+ Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
+ Log.d(TAG, msg)
+ setSelectedStyle()
+ })
+ builder.show()
+ }
+
+ private fun setSelectedStyle() {
+ val style: MapStyleOptions?
+ val id = mSelectedStyleId
+ style = when (id) {
+ com.example.common_ui.R.string.style_label_retro ->
+ MapStyleOptions.loadRawResourceStyle(this, com.example.common_ui.R.raw.mapstyle_retro)
+ com.example.common_ui.R.string.style_label_night ->
+ MapStyleOptions.loadRawResourceStyle(this, com.example.common_ui.R.raw.mapstyle_night)
+ com.example.common_ui.R.string.style_label_grayscale ->
+ MapStyleOptions.loadRawResourceStyle(this, com.example.common_ui.R.raw.mapstyle_grayscale)
+ com.example.common_ui.R.string.style_label_no_pois_no_transit ->
+ MapStyleOptions(
+ "[" +
+ " {" +
+ " \"featureType\":\"poi.business\"," +
+ " \"elementType\":\"all\"," +
+ " \"stylers\":[" +
+ " {" +
+ " \"visibility\":\"off\"" +
+ " }" +
+ " ]" +
+ " }," +
+ " {" +
+ " \"featureType\":\"transit\"," +
+ " \"elementType\":\"all\"," +
+ " \"stylers\":[" +
+ " {" +
+ " \"visibility\":\"off\"" +
+ " }" +
+ " ]" +
+ " }" +
+ "]"
+ )
+ com.example.common_ui.R.string.style_label_default -> null
+ else -> return
+ }
+ mMap?.setMapStyle(style)
+ }
+}
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/TagsDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/TagsDemoActivity.kt
index d282bc03f..88bb4c194 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/TagsDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/TagsDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -88,7 +88,7 @@ class TagsDemoActivity : SamplesBaseActivity(),
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
OnMapAndViewReadyListener(mapFragment, this)
- applyInsets(findViewById(R.id.map_container))
+ applyInsets(findViewById(R.id.map_container))
}
override fun onMapReady(googleMap: GoogleMap?) {
diff --git a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt
index 5b4b75fb4..c48db2b93 100644
--- a/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/main/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package com.example.kotlindemos
import android.os.Bundle
import android.os.Handler
+import android.os.Looper
import android.os.SystemClock
import android.view.View
import android.view.animation.OvershootInterpolator
@@ -121,7 +122,7 @@ class VisibleRegionDemoActivity :
// this function smoothly changes the amount of padding over a period of time
private fun animatePadding(toLeft: Int, toTop: Int, toRight: Int, toBottom: Int) {
- val handler = Handler()
+ val handler = Handler(Looper.getMainLooper())
val start = SystemClock.uptimeMillis()
val duration: Long = 1000
diff --git a/ApiDemos/project/kotlin-app/src/main/res/layout/save_state_demo.xml b/ApiDemos/project/kotlin-app/src/main/res/layout/save_state_demo.xml
new file mode 100644
index 000000000..4291e256d
--- /dev/null
+++ b/ApiDemos/project/kotlin-app/src/main/res/layout/save_state_demo.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/MarkerDemoActivity.kt b/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/MarkerDemoActivity.kt
index 19db8ca20..afdc121fa 100644
--- a/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/MarkerDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/MarkerDemoActivity.kt
@@ -6,7 +6,7 @@
* corresponding file under the `app/src/gms` directory.
*/
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Handler
+import android.os.Looper
import android.os.SystemClock
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
@@ -46,7 +47,9 @@ import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat
+import androidx.core.graphics.createBitmap
import androidx.core.graphics.drawable.DrawableCompat
+import androidx.core.graphics.toColorInt
import com.google.android.libraries.maps.CameraUpdateFactory
import com.google.android.libraries.maps.GoogleMap
import com.google.android.libraries.maps.GoogleMap.InfoWindowAdapter
@@ -299,7 +302,7 @@ class MarkerDemoActivity :
position = places.getValue("ALICE_SPRINGS"),
title = "Alice Springs",
icon = vectorToBitmap(
- com.example.common_ui.R.drawable.ic_android, Color.parseColor("#A4C639"))
+ com.example.common_ui.R.drawable.ic_android, "#A4C639".toColorInt())
),
// More markers for good measure
@@ -371,8 +374,11 @@ class MarkerDemoActivity :
Log.e(TAG, "Resource not found")
return BitmapDescriptorFactory.defaultMarker()
}
- val bitmap = Bitmap.createBitmap(vectorDrawable.intrinsicWidth,
- vectorDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
+ val 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)
@@ -415,7 +421,7 @@ class MarkerDemoActivity :
if (marker.position == places.getValue("PERTH")) {
// This causes the marker at Perth to bounce into position when it is clicked.
- val handler = Handler()
+ val handler = Handler(Looper.getMainLooper())
val start = SystemClock.uptimeMillis()
val duration = 1500
diff --git a/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt b/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt
index decf452c9..d5cd25ece 100644
--- a/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt
+++ b/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt
@@ -6,7 +6,7 @@
* corresponding file under the `app/src/gms` directory.
*/
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ class OnMapAndViewReadyListener(
) : OnGlobalLayoutListener,
OnMapReadyCallback {
- private val mapView: View? = mapFragment.view
+ private var mapView: View? = null
private var isViewReady = false
private var isMapReady = false
@@ -59,15 +59,6 @@ class OnMapAndViewReadyListener(
}
private fun registerListeners() {
- // View layout.
- if (mapView?.width != 0 && mapView?.height != 0) {
- // View has already completed layout.
- isViewReady = true
- } else {
- // Map has not undergone layout, register a View observer.
- mapView.viewTreeObserver.addOnGlobalLayoutListener(this)
- }
-
// GoogleMap. Note if the GoogleMap is already ready it will still fire the callback later.
mapFragment.getMapAsync(this)
}
@@ -76,6 +67,22 @@ class OnMapAndViewReadyListener(
// NOTE: The GoogleMap API specifies the listener is removed just prior to invocation.
map = googleMap ?: return
isMapReady = true
+
+ // View layout.
+ mapView = mapFragment.view
+ val view = mapView
+ if (view != null) {
+ if (view.width != 0 && view.height != 0) {
+ // View has already completed layout.
+ isViewReady = true
+ } else {
+ // Map has not undergone layout, register a View observer.
+ view.viewTreeObserver.addOnGlobalLayoutListener(this)
+ }
+ } else {
+ isViewReady = true
+ }
+
fireCallbackIfReady()
}
diff --git a/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt b/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt
index f316a9843..30b9c0bad 100644
--- a/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt
+++ b/ApiDemos/project/kotlin-app/src/v3/java/com/example/kotlindemos/VisibleRegionDemoActivity.kt
@@ -6,7 +6,7 @@
* corresponding file under the `app/src/gms` directory.
*/
/*
- * Copyright 2018 Google LLC
+ * Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ package com.example.kotlindemos
import android.os.Bundle
import android.os.Handler
+import android.os.Looper
import android.os.SystemClock
import android.view.View
import android.view.animation.OvershootInterpolator
@@ -131,7 +132,7 @@ class VisibleRegionDemoActivity :
// this function smoothly changes the amount of padding over a period of time
private fun animatePadding(toLeft: Int, toTop: Int, toRight: Int, toBottom: Int) {
- val handler = Handler()
+ val handler = Handler(Looper.getMainLooper())
val start = SystemClock.uptimeMillis()
val duration: Long = 1000