diff --git a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsButton.kt b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsButton.kt index 353576ab..007b1d69 100644 --- a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsButton.kt +++ b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsButton.kt @@ -16,16 +16,11 @@ package com.example.maps3d.common -import android.app.Activity import android.content.Context -import android.content.ContextWrapper import android.util.AttributeSet import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.ViewCompat -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.WindowInsetsControllerCompat import com.example.maps3dcommon.R import com.google.android.gms.maps3d.GoogleMap3D import com.google.android.gms.maps3d.model.Map3DMode @@ -57,7 +52,7 @@ class Map3DQuickSettingsButton @JvmOverloads constructor( val map = attachedMap ?: mapProvider?.invoke() map?.let { updatedSettings.applyTo(it) } updateTopMarginForUiControls(updatedSettings.uiControls) - applyStatusBarInsetsToSiblingMapView() + requestSiblingMapViewInsets() onSettingsChangedListener?.onSettingsChanged(updatedSettings) } @@ -99,6 +94,7 @@ class Map3DQuickSettingsButton @JvmOverloads constructor( private var mapProvider: (() -> GoogleMap3D?)? = null private var activeDialog: AlertDialog? = null private var onSettingsChangedListener: OnSettingsChangedListener? = null + private var lastAppliedUiControls: Map3DUiControls? = null init { setImageResource(R.drawable.settings_24px) @@ -107,7 +103,7 @@ class Map3DQuickSettingsButton @JvmOverloads constructor( ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets -> updateTopMarginForUiControls() - applyStatusBarInsetsToSiblingMapView() + requestSiblingMapViewInsets() insets } @@ -118,39 +114,15 @@ class Map3DQuickSettingsButton @JvmOverloads constructor( override fun onAttachedToWindow() { super.onAttachedToWindow() - hideHostSystemBars() settingsController.addListener(controllerListener) updateTopMarginForUiControls() - applyStatusBarInsetsToSiblingMapView() + requestSiblingMapViewInsets() ViewCompat.requestApplyInsets(this) post { - hideHostSystemBars() updateTopMarginForUiControls() } } - override fun onWindowFocusChanged(hasWindowFocus: Boolean) { - super.onWindowFocusChanged(hasWindowFocus) - if (hasWindowFocus) { - hideHostSystemBars() - } - } - - private fun hideHostSystemBars() { - var ctx: Context? = context - while (ctx is ContextWrapper) { - if (ctx is Activity) { - val window = ctx.window - val insetsController = WindowCompat.getInsetsController(window, window.decorView) - insetsController.systemBarsBehavior = - WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - insetsController.hide(WindowInsetsCompat.Type.systemBars()) - break - } - ctx = ctx.baseContext - } - } - override fun onDetachedFromWindow() { activeDialog?.dismiss() activeDialog = null @@ -163,12 +135,9 @@ class Map3DQuickSettingsButton @JvmOverloads constructor( return parentGroup.findViewById(R.id.map3dView) } - private fun applyStatusBarInsetsToSiblingMapView() { + private fun requestSiblingMapViewInsets() { val mapView = findSiblingMapView() ?: return - Map3DSettings.applyStatusBarInsetsToMapView( - mapView = mapView, - explicitStatusBarTop = statusBarTopOffsetPx.takeIf { it > 0 }, - ) + ViewCompat.requestApplyInsets(mapView) } private fun resolveEffectiveStatusBarOffsetPx(): Int { @@ -178,12 +147,25 @@ class Map3DQuickSettingsButton @JvmOverloads constructor( return Map3DSettings.resolveStatusBarOverlapPx(mapView ?: parentGroup) } + /** + * Re-applies the top margin for the most recently configured [Map3DUiControls] (or the + * active [settingsController] controls if none have been explicitly set yet). + */ + fun updateTopMarginForUiControls() { + val controls = lastAppliedUiControls ?: getSettings().uiControls + applyTopMargin(controls) + } + /** * Adjusts this button's top margin so it sits directly below the active trailing camera UI * controls ([Map3DUiControls.zoom], [Map3DUiControls.tilt], [Map3DUiControls.rotate]). */ - @JvmOverloads - fun updateTopMarginForUiControls(uiControls: Map3DUiControls = getSettings().uiControls) { + fun updateTopMarginForUiControls(uiControls: Map3DUiControls) { + lastAppliedUiControls = uiControls + applyTopMargin(uiControls) + } + + private fun applyTopMargin(uiControls: Map3DUiControls) { val lp = layoutParams as? ViewGroup.MarginLayoutParams ?: return val density = resources.displayMetrics.density val baseMarginDp = uiControls.calculateFabMarginDp() @@ -203,17 +185,18 @@ class Map3DQuickSettingsButton @JvmOverloads constructor( fun attachMap(googleMap3D: GoogleMap3D?) { this.attachedMap = googleMap3D val currentSettings = settingsController.getSettings() - updateTopMarginForUiControls(currentSettings.uiControls) + updateTopMarginForUiControls() if (googleMap3D != null) { currentSettings.applyTo(googleMap3D) - applyStatusBarInsetsToSiblingMapView() + requestSiblingMapViewInsets() // Re-apply after a short delay to ensure native engine layout pass preserves controls postDelayed({ if (attachedMap == googleMap3D) { val latest = settingsController.getSettings() latest.applyTo(googleMap3D) - updateTopMarginForUiControls(latest.uiControls) - applyStatusBarInsetsToSiblingMapView() + updateTopMarginForUiControls() + requestSiblingMapViewInsets() + onSettingsChangedListener?.onSettingsChanged(latest) } }, 350L) } diff --git a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsDialog.kt b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsDialog.kt index d82d8120..184722d1 100644 --- a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsDialog.kt +++ b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsDialog.kt @@ -18,13 +18,9 @@ package com.example.maps3d.common import android.content.Context import android.view.LayoutInflater -import android.view.WindowManager import android.widget.Button import android.widget.RadioGroup import androidx.appcompat.app.AlertDialog -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.WindowInsetsControllerCompat import com.example.maps3dcommon.R import com.google.android.gms.maps3d.GoogleMap3D import com.google.android.gms.maps3d.model.Map3DMode @@ -188,18 +184,7 @@ object Map3DQuickSettingsDialog { dialog.dismiss() } - dialog.window?.setFlags( - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, - ) dialog.show() - dialog.window?.let { dialogWindow -> - val insetsController = WindowCompat.getInsetsController(dialogWindow, dialogWindow.decorView) - insetsController.systemBarsBehavior = - WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - insetsController.hide(WindowInsetsCompat.Type.systemBars()) - dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) - } return dialog } } diff --git a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsWidget.kt b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsWidget.kt index e2a4b562..0efd050c 100644 --- a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsWidget.kt +++ b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DQuickSettingsWidget.kt @@ -16,9 +16,6 @@ package com.example.maps3d.common -import android.app.Activity -import android.content.Context -import android.content.ContextWrapper import android.view.View import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement @@ -51,7 +48,6 @@ import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -67,9 +63,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.WindowInsetsControllerCompat +import androidx.core.view.ViewCompat import com.example.maps3dcommon.R import com.google.android.gms.maps3d.GoogleMap3D import com.google.android.gms.maps3d.model.Map3DMode @@ -94,23 +88,9 @@ fun rememberMap3DSessionSettings( ): State { val view = LocalView.current if (!view.isInEditMode) { - SideEffect { - var ctx: Context? = view.context - while (ctx is ContextWrapper) { - if (ctx is Activity) { - val window = ctx.window - val insetsController = WindowCompat.getInsetsController(window, window.decorView) - insetsController.systemBarsBehavior = - WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - insetsController.hide(WindowInsetsCompat.Type.systemBars()) - break - } - ctx = ctx.baseContext - } - } LaunchedEffect(Unit) { Map3DSettings.findMap3DView(view.rootView)?.let { mapView -> - Map3DSettings.applyStatusBarInsetsToMapView(mapView) + ViewCompat.requestApplyInsets(mapView) } } } @@ -180,8 +160,8 @@ fun Map3DQuickSettingsWidget( } effectiveSettings.applyTo(googleMap3D) Map3DSettings.findMap3DView(view.rootView)?.let { mapView -> - Map3DSettings.applyStatusBarInsetsToMapView(mapView) - mapView.post { Map3DSettings.applyStatusBarInsetsToMapView(mapView) } + ViewCompat.requestApplyInsets(mapView) + mapView.post { ViewCompat.requestApplyInsets(mapView) } } } } @@ -197,7 +177,7 @@ fun Map3DQuickSettingsWidget( } effectiveSettings.applyTo(googleMap3D) Map3DSettings.findMap3DView(view.rootView)?.let { mapView -> - Map3DSettings.applyStatusBarInsetsToMapView(mapView) + ViewCompat.requestApplyInsets(mapView) } } } diff --git a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DSettings.kt b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DSettings.kt index 8dae7a99..945f59c2 100644 --- a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DSettings.kt +++ b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Map3DSettings.kt @@ -18,11 +18,8 @@ package com.example.maps3d.common import android.annotation.SuppressLint import android.util.Log -import android.view.Gravity import android.view.View import android.view.ViewGroup -import android.widget.FrameLayout -import android.widget.LinearLayout import androidx.appcompat.app.AppCompatDelegate import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat @@ -216,11 +213,6 @@ data class Map3DSettings( return null } - private data class ControlMarginState( - val baseTopMargin: Int, - val appliedTopMargin: Int, - ) - /** * Resolves the status bar height (in pixels) for the given [view]. */ @@ -282,116 +274,6 @@ data class Map3DSettings( statusBarTop } } - - /** - * Offsets top-anchored SDK UI control containers (`ControlPlacement.LEADING` and - * `ControlPlacement.TRAILING`) inside [mapView] so the status bar does not overlap them - * when [mapView] is rendered full-screen. - * - * Workaround: [Map3DView] does not yet respect window insets or expose a padding API for - * its internal UI control overlays on edge-to-edge screens. Tracked in - * https://issuetracker.google.com/issues/575850758. - */ - @JvmStatic - @JvmOverloads - fun applyStatusBarInsetsToMapView( - mapView: ViewGroup, - explicitStatusBarTop: Int? = null, - ) { - // Workaround: Until Map3DView natively handles window insets or exposes map padding - // (https://issuetracker.google.com/issues/575850758), offset its top-aligned UI - // control containers when the map draws under the status bar. - if (explicitStatusBarTop != null) { - mapView.setTag( - R.id.map3d_status_bar_top_tag, - explicitStatusBarTop.coerceAtLeast(0), - ) - } - val effectiveExplicitTop = - explicitStatusBarTop ?: (mapView.getTag(R.id.map3d_status_bar_top_tag) as? Int) - val statusBarOverlap = resolveStatusBarOverlapPx(mapView, effectiveExplicitTop) - ensureRootLayoutListener(mapView) - offsetTopControlContainers(mapView, statusBarOverlap, mapView) - } - - private fun ensureRootLayoutListener(rootMapView: ViewGroup) { - if (rootMapView.getTag(R.id.map3d_insets_listener_tag) == true) return - rootMapView.setTag(R.id.map3d_insets_listener_tag, true) - - rootMapView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> - val cachedTop = rootMapView.getTag(R.id.map3d_status_bar_top_tag) as? Int - val overlap = resolveStatusBarOverlapPx(rootMapView, cachedTop) - offsetTopControlContainers(rootMapView, overlap, rootMapView) - } - } - - private fun ensureContainerLayoutListener(container: LinearLayout, rootMapView: ViewGroup) { - if (container.getTag(R.id.map3d_insets_listener_tag) == true) return - container.setTag(R.id.map3d_insets_listener_tag, true) - - container.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> - val cachedTop = rootMapView.getTag(R.id.map3d_status_bar_top_tag) as? Int - val overlap = resolveStatusBarOverlapPx(rootMapView, cachedTop) - applyMarginToControlContainer(container, overlap) - } - } - - private fun applyMarginToControlContainer( - container: LinearLayout, - statusBarOverlap: Int, - ) { - val lp = container.layoutParams as? ViewGroup.MarginLayoutParams ?: return - val state = container.getTag(R.id.map3d_base_top_margin_tag) as? ControlMarginState - val baseTopMargin = if (state == null || lp.topMargin != state.appliedTopMargin) { - lp.topMargin - } else { - state.baseTopMargin - } - val targetTopMargin = baseTopMargin + statusBarOverlap.coerceAtLeast(0) - container.setTag( - R.id.map3d_base_top_margin_tag, - ControlMarginState(baseTopMargin, targetTopMargin), - ) - if (lp.topMargin != targetTopMargin) { - lp.topMargin = targetTopMargin - container.layoutParams = lp - container.post { - if (container.isAttachedToWindow) { - container.requestLayout() - } - } - } - } - - private fun offsetTopControlContainers( - group: ViewGroup, - statusBarOverlap: Int, - rootMapView: ViewGroup, - ) { - for (i in 0 until group.childCount) { - val child = group.getChildAt(i) ?: continue - if (child is LinearLayout) { - val lp = child.layoutParams as? ViewGroup.MarginLayoutParams - val isTopAligned = when (lp) { - is FrameLayout.LayoutParams -> { - val vGravity = lp.gravity and Gravity.VERTICAL_GRAVITY_MASK - vGravity != Gravity.BOTTOM && vGravity != Gravity.CENTER_VERTICAL - } - null -> false - else -> !child.isLaidOut || child.top <= group.height / 2 - } - if (lp != null && isTopAligned) { - ensureContainerLayoutListener(child, rootMapView) - applyMarginToControlContainer(child, statusBarOverlap) - // Do not recurse into individual control views inside a control container - continue - } - } - if (child is ViewGroup) { - offsetTopControlContainers(child, statusBarOverlap, rootMapView) - } - } - } } } // [END maps_3d_quick_settings_model] diff --git a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Utilities.kt b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Utilities.kt index 1c241c13..5f8d4fbc 100644 --- a/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Utilities.kt +++ b/Maps3DSamples/ApiDemos/common/src/main/java/com/example/maps3d/common/Utilities.kt @@ -27,14 +27,14 @@ import java.util.Locale import kotlin.math.floor /** - * Enables sticky immersive mode so the 3D map canvas occupies the entire display, - * hiding status and navigation bars while allowing transient reveal on edge swipes. + * Configures system bar behavior for edge-to-edge 3D map rendering while keeping + * status and navigation bars visible so [WindowInsetsCompat.Type.systemBars] insets can be verified. */ fun Activity.enableImmersiveMode() { val insetsController = WindowCompat.getInsetsController(window, window.decorView) insetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - insetsController.hide(WindowInsetsCompat.Type.systemBars()) + insetsController.show(WindowInsetsCompat.Type.systemBars()) } const val DEFAULT_HEADING = 0.0 diff --git a/Maps3DSamples/ApiDemos/common/src/main/res/values/ids.xml b/Maps3DSamples/ApiDemos/common/src/main/res/values/ids.xml deleted file mode 100644 index 9296e397..00000000 --- a/Maps3DSamples/ApiDemos/common/src/main/res/values/ids.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - diff --git a/Maps3DSamples/ApiDemos/common/src/test/java/com/example/maps3d/common/Map3DStatusBarInsetsTest.kt b/Maps3DSamples/ApiDemos/common/src/test/java/com/example/maps3d/common/Map3DStatusBarInsetsTest.kt deleted file mode 100644 index 3ae3580e..00000000 --- a/Maps3DSamples/ApiDemos/common/src/test/java/com/example/maps3d/common/Map3DStatusBarInsetsTest.kt +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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.maps3d.common - -import android.content.Context -import android.os.Looper -import android.view.Gravity -import android.widget.FrameLayout -import android.widget.LinearLayout -import androidx.test.core.app.ApplicationProvider -import com.google.common.truth.Truth.assertThat -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.Shadows.shadowOf -import org.robolectric.annotation.LooperMode - -/** - * Unit tests verifying that [Map3DSettings.applyStatusBarInsetsToMapView] shifts top-anchored - * SDK UI control containers below the status bar without moving bottom-anchored overlays. - */ -@RunWith(RobolectricTestRunner::class) -@LooperMode(LooperMode.Mode.PAUSED) -class Map3DStatusBarInsetsTest { - - @Test - fun applyStatusBarInsetsToMapView_offsetsTopLeadingAndTrailingContainers() { - val context = ApplicationProvider.getApplicationContext() - val mapView = FrameLayout(context) - val baseMarginPx = (16 * context.resources.displayMetrics.density).toInt() - val statusBarPx = 96 - - val trailingControls = LinearLayout(context) - val trailingLp = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.TOP or Gravity.END, - ).apply { topMargin = baseMarginPx } - mapView.addView(trailingControls, trailingLp) - - val leadingControls = LinearLayout(context) - val leadingLp = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.TOP or Gravity.START, - ).apply { topMargin = baseMarginPx } - mapView.addView(leadingControls, leadingLp) - - val bottomControls = LinearLayout(context) - val bottomLp = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.BOTTOM or Gravity.START, - ).apply { topMargin = baseMarginPx } - mapView.addView(bottomControls, bottomLp) - - Map3DSettings.applyStatusBarInsetsToMapView(mapView, explicitStatusBarTop = statusBarPx) - - assertThat((trailingControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(statusBarPx + baseMarginPx) - assertThat((leadingControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(statusBarPx + baseMarginPx) - assertThat((bottomControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(baseMarginPx) - } - - @Test - fun applyStatusBarInsetsToMapView_reappliesInsetsWhenChildControlContainerAddedLater() { - val context = ApplicationProvider.getApplicationContext() - val mapView = FrameLayout(context) - val baseMarginPx = (16 * context.resources.displayMetrics.density).toInt() - val statusBarPx = 84 - - Map3DSettings.applyStatusBarInsetsToMapView(mapView, explicitStatusBarTop = statusBarPx) - - val delayedTrailingControls = LinearLayout(context) - val trailingLp = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.TOP or Gravity.END, - ).apply { topMargin = baseMarginPx } - mapView.addView(delayedTrailingControls, trailingLp) - - // Adding a child triggers a layout pass on the root map view - mapView.layout(0, 0, 1000, 1000) - shadowOf(Looper.getMainLooper()).idle() - - assertThat((delayedTrailingControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(statusBarPx + baseMarginPx) - } - - @Test - fun applyStatusBarInsetsToMapView_recoversWhenNestedDelegateResetsTopMargin() { - val context = ApplicationProvider.getApplicationContext() - val mapView = FrameLayout(context) - val delegateFrame = FrameLayout(context) - mapView.addView( - delegateFrame, - FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.MATCH_PARENT, - ), - ) - - val baseMarginPx = (16 * context.resources.displayMetrics.density).toInt() - val statusBarPx = 90 - - val nestedTrailingControls = LinearLayout(context) - val trailingLp = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.TOP or Gravity.END, - ).apply { topMargin = baseMarginPx } - delegateFrame.addView(nestedTrailingControls, trailingLp) - - Map3DSettings.applyStatusBarInsetsToMapView(mapView, explicitStatusBarTop = statusBarPx) - assertThat((nestedTrailingControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(statusBarPx + baseMarginPx) - - // Simulate SDK setUiControlsPlacement resetting topMargin on the nested container - val resetLp = (nestedTrailingControls.layoutParams as FrameLayout.LayoutParams).apply { - topMargin = baseMarginPx - } - nestedTrailingControls.layoutParams = resetLp - nestedTrailingControls.layout(0, 0, 100, 300) - shadowOf(Looper.getMainLooper()).idle() - - assertThat((nestedTrailingControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(statusBarPx + baseMarginPx) - } - - @Test - fun applyStatusBarInsetsToMapView_clearsCachedTopAndRestoresSdkBaseMarginWhenZeroPassed() { - val context = ApplicationProvider.getApplicationContext() - val mapView = FrameLayout(context) - val customSdkBaseMarginPx = 24 - val statusBarPx = 80 - - val trailingControls = LinearLayout(context) - val trailingLp = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, - Gravity.TOP or Gravity.END, - ).apply { topMargin = customSdkBaseMarginPx } - mapView.addView(trailingControls, trailingLp) - - Map3DSettings.applyStatusBarInsetsToMapView(mapView, explicitStatusBarTop = statusBarPx) - assertThat((trailingControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(customSdkBaseMarginPx + statusBarPx) - - // Passing explicit 0 should clear the cached positive inset and restore the SDK's exact base margin - Map3DSettings.applyStatusBarInsetsToMapView(mapView, explicitStatusBarTop = 0) - assertThat((trailingControls.layoutParams as FrameLayout.LayoutParams).topMargin) - .isEqualTo(customSdkBaseMarginPx) - } -} diff --git a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/hellomap/HelloMapActivity.java b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/hellomap/HelloMapActivity.java index 3a756cc8..86a502d6 100644 --- a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/hellomap/HelloMapActivity.java +++ b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/hellomap/HelloMapActivity.java @@ -64,7 +64,7 @@ private void enableImmersiveMode() { if (insetsController != null) { insetsController.setSystemBarsBehavior( WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE); - insetsController.hide(WindowInsetsCompat.Type.systemBars()); + insetsController.show(WindowInsetsCompat.Type.systemBars()); } } diff --git a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/sampleactivity/SampleBaseActivity.java b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/sampleactivity/SampleBaseActivity.java index 8912f552..af30a5be 100644 --- a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/sampleactivity/SampleBaseActivity.java +++ b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/sampleactivity/SampleBaseActivity.java @@ -99,14 +99,17 @@ private void applyStatusBarInsetsToMapControls(Integer statusBarTop, Map3DUiCont lastStatusBarTop = statusBarTop; } if (map3DView != null) { - Map3DSettings.applyStatusBarInsetsToMapView(map3DView, lastStatusBarTop); + ViewCompat.requestApplyInsets(map3DView); } Map3DQuickSettingsButton quickSettingsButton = findViewById(R.id.quick_settings_button); if (quickSettingsButton != null) { - Map3DUiControls currentUi = uiControls != null ? uiControls : quickSettingsButton.getSettings().getUiControls(); quickSettingsButton.setStatusBarTopOffsetPx(lastStatusBarTop != null ? lastStatusBarTop : 0); - quickSettingsButton.updateTopMarginForUiControls(currentUi); + if (uiControls != null) { + quickSettingsButton.updateTopMarginForUiControls(uiControls); + } else { + quickSettingsButton.updateTopMarginForUiControls(); + } } } @@ -123,7 +126,7 @@ private void bindWindowInsetsAndMapHierarchy() { lastStatusBarTop = 0; Map3DView currentMapView = findViewById(R.id.map3dView); if (currentMapView != null) { - Map3DSettings.applyStatusBarInsetsToMapView(currentMapView, 0); + ViewCompat.requestApplyInsets(currentMapView); } Map3DQuickSettingsButton button = findViewById(R.id.quick_settings_button); if (button != null) { @@ -155,13 +158,13 @@ private void bindWindowInsetsAndMapHierarchy() { controlScrollView.setLayoutParams(layoutParams); } - return WindowInsetsCompat.CONSUMED; + return windowInsets; }); } Map3DView currentMapView = findViewById(R.id.map3dView); if (currentMapView != null) { - Map3DSettings.applyStatusBarInsetsToMapView(currentMapView, lastStatusBarTop); + ViewCompat.requestApplyInsets(currentMapView); } } diff --git a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/uicontrols/UiControlsActivity.java b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/uicontrols/UiControlsActivity.java index 7ddaa781..b07cd39a 100644 --- a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/uicontrols/UiControlsActivity.java +++ b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/uicontrols/UiControlsActivity.java @@ -30,6 +30,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.cardview.widget.CardView; +import androidx.core.view.ViewCompat; import com.example.maps3d.common.Map3DQuickSettingsButton; import com.example.maps3d.common.Map3DSettings; import com.example.maps3d.common.Map3DUiControls; @@ -140,6 +141,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { ViewGroup container = findViewById(R.id.map_container); if (container != null) { getLayoutInflater().inflate(R.layout.control_panel_ui_controls, container, true); + ViewCompat.requestApplyInsets(container); } MaterialToolbar topBar = findViewById(R.id.top_bar); @@ -221,9 +223,28 @@ private void initViews() { }); } + Map3DQuickSettingsButton initialButton = findViewById(R.id.quick_settings_button); + if (initialButton != null) { + initialButton.updateTopMarginForUiControls(buildCurrentUiControls()); + } + fadeHandler.postDelayed(fadeOutRunnable, 3000L); } + private Map3DUiControls buildCurrentUiControls() { + boolean isLeading = + rgPlacement != null && rgPlacement.getCheckedRadioButtonId() == R.id.rb_placement_leading; + int primaryPlacement = isLeading ? ControlPlacement.LEADING : ControlPlacement.TRAILING; + return new Map3DUiControls( + chipZoom != null && chipZoom.isChecked(), + chipTilt != null && chipTilt.isChecked(), + chipRotate != null && chipRotate.isChecked(), + chipCompass != null && chipCompass.isChecked(), + chipPanVertical != null && chipPanVertical.isChecked(), + chipPanHorizontal != null && chipPanHorizontal.isChecked(), + primaryPlacement); + } + private void setAllChips(boolean checked) { isSyncingUi = true; if (chipZoom != null) chipZoom.setChecked(checked); @@ -239,6 +260,12 @@ private void setAllChips(boolean checked) { * Applies the UI controls configuration directly to the {@link GoogleMap3D} instance using the SDK API. */ private void applyControlsToMap() { + Map3DUiControls localUiControls = buildCurrentUiControls(); + Map3DQuickSettingsButton quickSettingsButton = findViewById(R.id.quick_settings_button); + if (quickSettingsButton != null) { + quickSettingsButton.updateTopMarginForUiControls(localUiControls); + } + if (googleMap3D == null) { return; } @@ -248,49 +275,38 @@ private void applyControlsToMap() { } List primaryControls = new ArrayList<>(); - if (chipZoom != null && chipZoom.isChecked()) { + if (localUiControls.getZoom()) { primaryControls.add(new ZoomControl(ControlOrientation.VERTICAL)); } - if (chipTilt != null && chipTilt.isChecked()) { + if (localUiControls.getTilt()) { primaryControls.add(new TiltControl(ControlOrientation.VERTICAL)); } - if (chipRotate != null && chipRotate.isChecked()) { + if (localUiControls.getRotate()) { primaryControls.add(new RotateControl(ControlOrientation.VERTICAL)); } List secondaryControls = new ArrayList<>(); - if (chipPanVertical != null && chipPanVertical.isChecked()) { + if (localUiControls.getPanVertical()) { secondaryControls.add(new PanVerticalControl(ControlOrientation.VERTICAL)); } - if (chipPanHorizontal != null && chipPanHorizontal.isChecked()) { + if (localUiControls.getPanHorizontal()) { secondaryControls.add(new PanHorizontalControl(ControlOrientation.VERTICAL)); } - if (chipCompass != null && chipCompass.isChecked()) { + if (localUiControls.getCompass()) { secondaryControls.add(new CompassControl()); } - boolean isLeading = rgPlacement != null && rgPlacement.getCheckedRadioButtonId() == R.id.rb_placement_leading; - int primaryPlacement = isLeading ? ControlPlacement.LEADING : ControlPlacement.TRAILING; - int secondaryPlacement = isLeading ? ControlPlacement.TRAILING : ControlPlacement.LEADING; + int primaryPlacement = localUiControls.getControlsPosition(); + int secondaryPlacement = + primaryPlacement == ControlPlacement.LEADING + ? ControlPlacement.TRAILING + : ControlPlacement.LEADING; uiSettings.setUiControlsPlacement(primaryControls, primaryPlacement); uiSettings.setUiControlsPlacement(secondaryControls, secondaryPlacement); - Map3DUiControls localUiControls = new Map3DUiControls( - chipZoom != null && chipZoom.isChecked(), - chipTilt != null && chipTilt.isChecked(), - chipRotate != null && chipRotate.isChecked(), - chipCompass != null && chipCompass.isChecked(), - chipPanVertical != null && chipPanVertical.isChecked(), - chipPanHorizontal != null && chipPanHorizontal.isChecked(), - primaryPlacement - ); - Map3DQuickSettingsButton quickSettingsButton = findViewById(R.id.quick_settings_button); - if (quickSettingsButton != null) { - quickSettingsButton.updateTopMarginForUiControls(localUiControls); - } if (map3DView != null) { - Map3DSettings.applyStatusBarInsetsToMapView(map3DView); - map3DView.post(() -> Map3DSettings.applyStatusBarInsetsToMapView(map3DView)); + ViewCompat.requestApplyInsets(map3DView); + map3DView.post(() -> ViewCompat.requestApplyInsets(map3DView)); } } diff --git a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/hellomap/HelloMapActivity.kt b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/hellomap/HelloMapActivity.kt index 05886a66..bc3043a1 100644 --- a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/hellomap/HelloMapActivity.kt +++ b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/hellomap/HelloMapActivity.kt @@ -69,7 +69,7 @@ class HelloMapActivity : AppCompatActivity(), OnMap3DViewReadyCallback { val insetsController = WindowCompat.getInsetsController(window, window.decorView) insetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - insetsController.hide(WindowInsetsCompat.Type.systemBars()) + insetsController.show(WindowInsetsCompat.Type.systemBars()) } override fun onWindowFocusChanged(hasFocus: Boolean) { diff --git a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/sampleactivity/SampleBaseActivity.kt b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/sampleactivity/SampleBaseActivity.kt index 64761770..c5d8c097 100644 --- a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/sampleactivity/SampleBaseActivity.kt +++ b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/sampleactivity/SampleBaseActivity.kt @@ -152,13 +152,16 @@ abstract class SampleBaseActivity : AppCompatActivity(), OnMap3DViewReadyCallbac lastStatusBarTop = statusBarTop } if (::map3DView.isInitialized) { - Map3DSettings.applyStatusBarInsetsToMapView(map3DView, lastStatusBarTop) + ViewCompat.requestApplyInsets(map3DView) } // Keep the Quick Settings FAB directly below the active trailing controls findViewById(R.id.quick_settings_button)?.let { button -> - val currentUi = uiControls ?: button.getSettings().uiControls button.statusBarTopOffsetPx = lastStatusBarTop ?: 0 - button.updateTopMarginForUiControls(currentUi) + if (uiControls != null) { + button.updateTopMarginForUiControls(uiControls) + } else { + button.updateTopMarginForUiControls() + } } } @@ -173,7 +176,7 @@ abstract class SampleBaseActivity : AppCompatActivity(), OnMap3DViewReadyCallbac if (!hasOverlayAppBar) { lastStatusBarTop = 0 findViewById(R.id.map3dView)?.let { currentMapView -> - Map3DSettings.applyStatusBarInsetsToMapView(currentMapView, 0) + ViewCompat.requestApplyInsets(currentMapView) } findViewById(R.id.quick_settings_button)?.let { button -> button.statusBarTopOffsetPx = 0 @@ -201,12 +204,12 @@ abstract class SampleBaseActivity : AppCompatActivity(), OnMap3DViewReadyCallbac scrollView.layoutParams = layoutParams } - WindowInsetsCompat.CONSUMED + insets } } findViewById(R.id.map3dView)?.let { currentMapView -> - Map3DSettings.applyStatusBarInsetsToMapView(currentMapView, lastStatusBarTop) + ViewCompat.requestApplyInsets(currentMapView) } } diff --git a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/uicontrols/UiControlsActivity.kt b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/uicontrols/UiControlsActivity.kt index a99e9129..88267912 100644 --- a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/uicontrols/UiControlsActivity.kt +++ b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/uicontrols/UiControlsActivity.kt @@ -25,6 +25,7 @@ import android.view.View import android.view.ViewGroup import android.widget.RadioGroup import androidx.cardview.widget.CardView +import androidx.core.view.ViewCompat import com.example.maps3d.common.Map3DQuickSettingsButton import com.example.maps3d.common.Map3DSettings import com.example.maps3d.common.Map3DUiControls @@ -123,6 +124,7 @@ class UiControlsActivity : SampleBaseActivity() { // Inflate UI controls panel overlay into map container managed by SampleBaseActivity findViewById(R.id.map_container)?.let { container -> layoutInflater.inflate(R.layout.control_panel_ui_controls, container, true) + ViewCompat.requestApplyInsets(container) } findViewById(R.id.top_bar)?.apply { @@ -185,9 +187,26 @@ class UiControlsActivity : SampleBaseActivity() { } } + findViewById(R.id.quick_settings_button) + ?.updateTopMarginForUiControls(buildCurrentUiControls()) + fadeHandler.postDelayed(fadeOutRunnable, 3000L) } + private fun buildCurrentUiControls(): Map3DUiControls { + val isLeading = rgPlacement?.checkedRadioButtonId == R.id.rb_placement_leading + val primaryPlacement = if (isLeading) ControlPlacement.LEADING else ControlPlacement.TRAILING + return Map3DUiControls( + zoom = chipZoom?.isChecked == true, + tilt = chipTilt?.isChecked == true, + rotate = chipRotate?.isChecked == true, + compass = chipCompass?.isChecked == true, + panVertical = chipPanVertical?.isChecked == true, + panHorizontal = chipPanHorizontal?.isChecked == true, + controlsPosition = primaryPlacement, + ) + } + private fun setAllChips(checked: Boolean) { isSyncingUi = true chipZoom?.isChecked = checked @@ -203,39 +222,32 @@ class UiControlsActivity : SampleBaseActivity() { * Applies the UI controls configuration directly to the [GoogleMap3D] instance using the SDK API. */ private fun applyControlsToMap() { + val localUiControls = buildCurrentUiControls() + findViewById(R.id.quick_settings_button) + ?.updateTopMarginForUiControls(localUiControls) + val map = googleMap3D ?: return val uiSettings = map.getUiControlSettings() ?: return val primaryControls = mutableListOf() - if (chipZoom?.isChecked == true) primaryControls.add(ZoomControl(ControlOrientation.VERTICAL)) - if (chipTilt?.isChecked == true) primaryControls.add(TiltControl(ControlOrientation.VERTICAL)) - if (chipRotate?.isChecked == true) primaryControls.add(RotateControl(ControlOrientation.VERTICAL)) + if (localUiControls.zoom) primaryControls.add(ZoomControl(ControlOrientation.VERTICAL)) + if (localUiControls.tilt) primaryControls.add(TiltControl(ControlOrientation.VERTICAL)) + if (localUiControls.rotate) primaryControls.add(RotateControl(ControlOrientation.VERTICAL)) val secondaryControls = mutableListOf() - if (chipPanVertical?.isChecked == true) secondaryControls.add(PanVerticalControl(ControlOrientation.VERTICAL)) - if (chipPanHorizontal?.isChecked == true) secondaryControls.add(PanHorizontalControl(ControlOrientation.VERTICAL)) - if (chipCompass?.isChecked == true) secondaryControls.add(CompassControl()) + if (localUiControls.panVertical) secondaryControls.add(PanVerticalControl(ControlOrientation.VERTICAL)) + if (localUiControls.panHorizontal) secondaryControls.add(PanHorizontalControl(ControlOrientation.VERTICAL)) + if (localUiControls.compass) secondaryControls.add(CompassControl()) - val isLeading = rgPlacement?.checkedRadioButtonId == R.id.rb_placement_leading - val primaryPlacement = if (isLeading) ControlPlacement.LEADING else ControlPlacement.TRAILING - val secondaryPlacement = if (isLeading) ControlPlacement.TRAILING else ControlPlacement.LEADING + val primaryPlacement = localUiControls.controlsPosition + val secondaryPlacement = + if (primaryPlacement == ControlPlacement.LEADING) ControlPlacement.TRAILING else ControlPlacement.LEADING uiSettings.setUiControlsPlacement(primaryControls, primaryPlacement) uiSettings.setUiControlsPlacement(secondaryControls, secondaryPlacement) - val localUiControls = Map3DUiControls( - zoom = chipZoom?.isChecked == true, - tilt = chipTilt?.isChecked == true, - rotate = chipRotate?.isChecked == true, - compass = chipCompass?.isChecked == true, - panVertical = chipPanVertical?.isChecked == true, - panHorizontal = chipPanHorizontal?.isChecked == true, - controlsPosition = primaryPlacement, - ) - findViewById(R.id.quick_settings_button) - ?.updateTopMarginForUiControls(localUiControls) - Map3DSettings.applyStatusBarInsetsToMapView(map3DView) + ViewCompat.requestApplyInsets(map3DView) map3DView.post { - Map3DSettings.applyStatusBarInsetsToMapView(map3DView) + ViewCompat.requestApplyInsets(map3DView) } } diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/camerarestrictions/CameraRestrictionsActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/camerarestrictions/CameraRestrictionsActivity.kt index 99424c91..1c1de192 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/camerarestrictions/CameraRestrictionsActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/camerarestrictions/CameraRestrictionsActivity.kt @@ -61,7 +61,7 @@ class CameraRestrictionsActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE setContent { diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/hellomap/HelloMapActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/hellomap/HelloMapActivity.kt index 91a4abe6..e46c56e0 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/hellomap/HelloMapActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/hellomap/HelloMapActivity.kt @@ -58,7 +58,7 @@ class HelloMapActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE setContent { diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/markers/MarkersActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/markers/MarkersActivity.kt index 3e304b57..b3452631 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/markers/MarkersActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/markers/MarkersActivity.kt @@ -113,7 +113,7 @@ class MarkersActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/models/ModelsActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/models/ModelsActivity.kt index c6c03d52..3a3bb7d0 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/models/ModelsActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/models/ModelsActivity.kt @@ -73,7 +73,7 @@ class ModelsActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE setContent { diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/placedetails/PlaceDetailsActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/placedetails/PlaceDetailsActivity.kt index eb8997b1..88d0af7d 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/placedetails/PlaceDetailsActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/placedetails/PlaceDetailsActivity.kt @@ -180,7 +180,7 @@ class PlaceDetailsActivity : FragmentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE setContent { diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polygons/PolygonsActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polygons/PolygonsActivity.kt index ab164119..b49e48dd 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polygons/PolygonsActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polygons/PolygonsActivity.kt @@ -87,7 +87,7 @@ class PolygonsActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polylines/PolylinesActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polylines/PolylinesActivity.kt index beae0799..aeb87474 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polylines/PolylinesActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/polylines/PolylinesActivity.kt @@ -66,7 +66,7 @@ class PolylinesActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE setContent { diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/popovers/PopoversActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/popovers/PopoversActivity.kt index 428173e4..0737383c 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/popovers/PopoversActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/popovers/PopoversActivity.kt @@ -92,7 +92,7 @@ class PopoversActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/routes/RoutesActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/routes/RoutesActivity.kt index 98aa1c74..e033e1ad 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/routes/RoutesActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/routes/RoutesActivity.kt @@ -168,7 +168,7 @@ class RoutesActivity : ComponentActivity() { // Hide system tray (immersive mode) val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE setContent { diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/storelocator/StoreLocatorActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/storelocator/StoreLocatorActivity.kt index 11dfc62a..a37b42cd 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/storelocator/StoreLocatorActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/storelocator/StoreLocatorActivity.kt @@ -111,7 +111,7 @@ class StoreLocatorActivity : ComponentActivity() { enableEdgeToEdge() val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) - windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + windowInsetsController.show(WindowInsetsCompat.Type.systemBars()) windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE diff --git a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/uicontrols/UiControlsActivity.kt b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/uicontrols/UiControlsActivity.kt index fae011db..059becca 100644 --- a/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/uicontrols/UiControlsActivity.kt +++ b/Maps3DSamples/ComposeDemos/app/src/main/java/com/example/composedemos/uicontrols/UiControlsActivity.kt @@ -32,6 +32,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.width @@ -62,6 +63,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.core.view.ViewCompat import com.example.maps3d.common.Map3DQuickSettingsWidget import com.example.maps3d.common.Map3DSessionTheme import com.example.maps3d.common.Map3DSettings @@ -187,9 +189,9 @@ fun UiControlsScreen() { uiSettings.setUiControlsPlacement(primaryControls, primaryPlacement) uiSettings.setUiControlsPlacement(secondaryControls, secondaryPlacement) Map3DSettings.findMap3DView(view.rootView)?.let { mapView -> - Map3DSettings.applyStatusBarInsetsToMapView(mapView) + ViewCompat.requestApplyInsets(mapView) mapView.post { - Map3DSettings.applyStatusBarInsetsToMapView(mapView) + ViewCompat.requestApplyInsets(mapView) } } } @@ -208,6 +210,7 @@ fun UiControlsScreen() { modifier = Modifier .align(Alignment.BottomCenter) .fillMaxWidth() + .navigationBarsPadding() .padding(12.dp), shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), diff --git a/maps3d-compose/src/main/java/com/google/maps/android/compose3d/GoogleMap3D.kt b/maps3d-compose/src/main/java/com/google/maps/android/compose3d/GoogleMap3D.kt index 7789338f..466a8ee4 100644 --- a/maps3d-compose/src/main/java/com/google/maps/android/compose3d/GoogleMap3D.kt +++ b/maps3d-compose/src/main/java/com/google/maps/android/compose3d/GoogleMap3D.kt @@ -25,6 +25,7 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.view.ViewCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.compose.LocalLifecycleOwner @@ -166,6 +167,10 @@ fun GoogleMap3D( googleMap3D.setMapMode(mapMode) googleMap3D.setCamera(initialValidCamera) Map3DRegistry.setInstance(googleMap3D) + ViewCompat.requestApplyInsets(map3dView) + map3dView.post { + ViewCompat.requestApplyInsets(map3dView) + } googleMap3D.setOnMapReadyListener { googleMap3D.setOnMapReadyListener(null)