diff --git a/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Android.cs b/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Android.cs index 57d89a239128..abe5e4b40480 100644 --- a/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Android.cs +++ b/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Android.cs @@ -53,6 +53,15 @@ public static void MapCurrentItem(CarouselViewHandler handler, CarouselView caro (handler.PlatformView as IMauiCarouselRecyclerView).UpdateFromCurrentItem(); } + // TODO: Change the modifier to public in .NET 10. + internal static void MapItemsLayout(CarouselViewHandler handler, CarouselView carouselView) + { + if (handler.PlatformView is IMauiRecyclerView recyclerView) + { + recyclerView.UpdateLayoutManager(); + } + } + public override Size GetDesiredSize(double widthConstraint, double heightConstraint) { _widthConstraint = widthConstraint; diff --git a/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.cs b/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.cs index 55f6dafa4d70..019796a0c899 100644 --- a/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.cs +++ b/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.cs @@ -14,7 +14,7 @@ public CarouselViewHandler(PropertyMapper mapper = null) : base(mapper ?? Mapper public static PropertyMapper Mapper = new(ItemsViewMapper) { -#if TIZEN +#if TIZEN || ANDROID [Controls.CarouselView.ItemsLayoutProperty.PropertyName] = MapItemsLayout, #endif [Controls.CarouselView.IsSwipeEnabledProperty.PropertyName] = MapIsSwipeEnabled, diff --git a/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs b/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs index 6a28c0a915dd..71051a2bb6dd 100644 --- a/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs +++ b/src/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.iOS.cs @@ -27,7 +27,8 @@ public CarouselViewHandler2(PropertyMapper mapper = null) : base(mapper ?? Mappe [Controls.CarouselView.PeekAreaInsetsProperty.PropertyName] = MapPeekAreaInsets, [Controls.CarouselView.IsBounceEnabledProperty.PropertyName] = MapIsBounceEnabled, [Controls.CarouselView.PositionProperty.PropertyName] = MapPosition, - [Controls.CarouselView.CurrentItemProperty.PropertyName] = MapCurrentItem + [Controls.CarouselView.CurrentItemProperty.PropertyName] = MapCurrentItem, + [Controls.CarouselView.ItemsLayoutProperty.PropertyName] = MapItemsLayout, }; } @@ -190,6 +191,12 @@ public static void MapIsBounceEnabled(CarouselViewHandler2 handler, CarouselView handler.Controller.CollectionView.Bounces = carouselView.IsBounceEnabled; } + // TODO: Change the modifier to public in .NET 10. + internal static void MapItemsLayout(CarouselViewHandler2 handler, CarouselView carouselView) + { + handler?.UpdateLayout(); + } + public static void MapPeekAreaInsets(CarouselViewHandler2 handler, CarouselView carouselView) { handler.UpdateLayout(); diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/VerifyCarouselLayoutOrientationChange.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/VerifyCarouselLayoutOrientationChange.png new file mode 100644 index 000000000000..2cbe08888f18 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/VerifyCarouselLayoutOrientationChange.png differ diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue29372.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue29372.cs new file mode 100644 index 000000000000..4a2ab45c5499 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue29372.cs @@ -0,0 +1,73 @@ +using System.Collections.ObjectModel; + +namespace Maui.Controls.Sample.Issues; +[Issue(IssueTracker.Github, 29372, "CarouselView ItemsLayout Not Updating at Runtime", PlatformAffected.All)] +public partial class Issue29372 : ContentPage +{ + public Issue29372() + { + var verticalStackLayout = new VerticalStackLayout(); + var carouselItems = new ObservableCollection + { + "Item 0", + "Item 1", + "Item 2", + "Item 3", + "Item 4", + }; + + CarouselView2 carouselView = new CarouselView2 + { + ItemsSource = carouselItems, + AutomationId = "carouselview", + ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal), + PeekAreaInsets = new Thickness(0, 100), + HeightRequest = 300, + Loop = false, + ItemTemplate = new DataTemplate(() => + { + var grid = new Grid + { + Padding = 10 + }; + + var label = new Label + { + VerticalOptions = LayoutOptions.Center, + HorizontalOptions = LayoutOptions.Center, + FontSize = 18, + }; + label.SetBinding(Label.TextProperty, "."); + label.SetBinding(Label.AutomationIdProperty, "."); + + grid.Children.Add(label); + return grid; + }), + HorizontalOptions = LayoutOptions.Fill, + }; + + var button = new Button + { + Text = "Change Items Layout", + AutomationId = "ChangeItemsLayoutButton", + Margin = new Thickness(20), + }; + + var label = new Label + { + Text = "The test is passed if the items are displayed in a vertical orientation.", + HorizontalOptions = LayoutOptions.Center, + Padding = new Thickness(20), + }; + + button.Clicked += (sender, e) => + { + carouselView.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical); + }; + + verticalStackLayout.Children.Add(label); + verticalStackLayout.Children.Add(carouselView); + verticalStackLayout.Children.Add(button); + Content = verticalStackLayout; + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29372.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29372.cs new file mode 100644 index 000000000000..ef1998bebc3f --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29372.cs @@ -0,0 +1,24 @@ +#if TEST_FAILS_ON_WINDOWS // Related issue for windows: https://github.com/dotnet/maui/issues/29445 +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; +public class Issue29372 : _IssuesUITest +{ + public override string Issue => "CarouselView ItemsLayout Not Updating at Runtime"; + + public Issue29372(TestDevice device) + : base(device) + { } + + [Test] + [Category(UITestCategories.CarouselView)] + public void VerifyCarouselLayoutOrientationChange() + { + App.WaitForElement("carouselview"); + App.Tap("ChangeItemsLayoutButton"); + VerifyScreenshot(); + } +} +#endif \ No newline at end of file diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCarouselLayoutOrientationChange.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCarouselLayoutOrientationChange.png new file mode 100644 index 000000000000..6a80ee610b5e Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyCarouselLayoutOrientationChange.png differ