diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cs index c243bacdc684..c3fbad7bd18c 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cs @@ -407,6 +407,15 @@ void UpdateScrim(Brush backdrop) } } + protected override void OnLayout(bool changed, int left, int top, int right, int bottom) + { + base.OnLayout(changed, left, top, right, bottom); + + var destination = Context.ToCrossPlatformRectInReferenceFrame(left, top, right, bottom); + if (Shell.Frame != destination) + Shell.Frame = destination; + } + internal void Disconnect() { ShellController?.RemoveAppearanceObserver(this); diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs index 4568795b1fef..aeb289655c95 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs @@ -141,6 +141,10 @@ public override void ViewDidLayoutSubviews() base.ViewDidLayoutSubviews(); if (_currentShellItemRenderer != null) _currentShellItemRenderer.ViewController.View.Frame = View.Bounds; + + var destination = View.Bounds.ToRectangle(); + if (Shell.Frame != destination) + Shell.Frame = destination; } public override void ViewDidLoad() diff --git a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt index cc66326af4d7..b494b4067850 100644 --- a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt @@ -1,4 +1,5 @@ #nullable enable +override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.OnLayout(bool changed, int left, int top, int right, int bottom) -> void override Microsoft.Maui.Controls.Shapes.Shape.OnPropertyChanged(string? propertyName = null) -> void ~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView.OnInterceptTouchEvent(Android.Views.MotionEvent e) -> bool ~override Microsoft.Maui.Controls.Handlers.Items.MauiRecyclerView.OnTouchEvent(Android.Views.MotionEvent e) -> bool diff --git a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs index 9b2c887e8a1f..eff3c01e31a1 100644 --- a/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs +++ b/src/Controls/tests/DeviceTests/Elements/Shell/ShellTests.cs @@ -1139,6 +1139,32 @@ await CreateHandlerAndAddToWindow(shell, _ => }); } + [Fact] + public async Task SettingFrameDoesTriggerInvalidatedMeasure() + { + SetupBuilder(); + + int measureInvalidatedCount = 0; + + var page = new ContentPage(); + var shell = await CreateShellAsync(shell => + { + shell.CurrentItem = new ShellContent { Content = page }; + }); + + shell.MeasureInvalidated += (s, e) => + { + measureInvalidatedCount++; + }; + + shell.Frame = new Microsoft.Maui.Graphics.Rect(0, 0, 100, 100); + + await CreateHandlerAndAddToWindow(shell, _ => + { + Assert.Equal(1, measureInvalidatedCount); + }); + } + protected Task CreateShellAsync(Action action) => InvokeOnMainThreadAsync(() => {