Skip to content

Commit 7143174

Browse files
authored
Fixed CarouselView Loop="False" rendering items incorrectly (dotnet#25545)
* Fixed CarouselView Loop="False" rendering items incorrectly * Added snapshots
1 parent 83d9676 commit 7143174

File tree

7 files changed

+169
-34
lines changed

7 files changed

+169
-34
lines changed

src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -571,46 +571,42 @@ void ClearLayoutListener()
571571

572572
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
573573
{
574-
if (Carousel.Loop)
574+
// If the height or width are unbounded and the user is set to
575+
// Loop then we can't just do an infinite measure.
576+
// Looping works by setting item count to 16384 so if the
577+
// CarV has infinite room it'll generate all 16384 items.
578+
// This code forces the adapter to just measure the first item
579+
// And then that measure is used for the WxH of the CarouselView
580+
581+
// I found that "AtMost" also causes this behavior so
582+
// that's why I'm turning "AtMost" into "Exactly"
583+
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.AtMost)
575584
{
576-
// If the height or width are unbounded and the user is set to
577-
// Loop then we can't just do an infinite measure.
578-
// Looping works by setting item count to 16384 so if the
579-
// CarV has infinite room it'll generate all 16384 items.
580-
// This code forces the adapter to just measure the first item
581-
// And then that measure is used for the WxH of the CarouselView
582-
583-
// I found that "AtMost" also causes this behavior so
584-
// that's why I'm turning "AtMost" into "Exactly"
585-
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.AtMost)
586-
{
587-
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(widthMeasureSpec.GetSize());
588-
}
585+
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(widthMeasureSpec.GetSize());
586+
}
589587

590-
if (MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.AtMost)
591-
{
592-
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(heightMeasureSpec.GetSize());
593-
}
588+
if (MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.AtMost)
589+
{
590+
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(heightMeasureSpec.GetSize());
591+
}
594592

595-
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.Unspecified ||
596-
MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.Unspecified)
593+
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.Unspecified ||
594+
MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.Unspecified)
595+
{
596+
if (ItemsViewAdapter.ItemCount > 0)
597597
{
598-
if (ItemsViewAdapter.ItemCount > 0)
599-
{
600-
// Retrieve the first item of the CarouselView and measure it
601-
// This is what we'll use for the CarV WxH if the requested measure
602-
// is for an infinite amount of space
603-
604-
var viewType = ItemsViewAdapter.GetItemViewType(0);
605-
var viewHolder = (ViewHolder)ItemsViewAdapter.CreateViewHolder(this, viewType);
606-
ItemsViewAdapter.BindViewHolder(viewHolder, 0);
607-
viewHolder.ItemView.Measure(widthMeasureSpec, heightMeasureSpec);
608-
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredWidth);
609-
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredHeight);
610-
}
598+
// Retrieve the first item of the CarouselView and measure it
599+
// This is what we'll use for the CarV WxH if the requested measure
600+
// is for an infinite amount of space
601+
602+
var viewType = ItemsViewAdapter.GetItemViewType(0);
603+
var viewHolder = (ViewHolder)ItemsViewAdapter.CreateViewHolder(this, viewType);
604+
ItemsViewAdapter.BindViewHolder(viewHolder, 0);
605+
viewHolder.ItemView.Measure(widthMeasureSpec, heightMeasureSpec);
606+
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredWidth);
607+
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredHeight);
611608
}
612609
}
613-
614610
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
615611
}
616612

34.9 KB
Loading
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
x:Class="Maui.Controls.Sample.Issues.Issue25192">
5+
<Grid>
6+
<CarouselView Margin="2,9,2,20"
7+
HeightRequest="180"
8+
Loop="False"
9+
PeekAreaInsets="20"
10+
VerticalOptions="End">
11+
<CarouselView.ItemsSource>
12+
<x:Array Type="{x:Type x:String}">
13+
<x:String>Item1</x:String>
14+
<x:String>Item2</x:String>
15+
<x:String>Item3</x:String>
16+
</x:Array>
17+
</CarouselView.ItemsSource>
18+
<CarouselView.ItemsLayout>
19+
<LinearItemsLayout ItemSpacing="5"
20+
Orientation="Horizontal"
21+
SnapPointsAlignment="Center"
22+
SnapPointsType="MandatorySingle"/>
23+
</CarouselView.ItemsLayout>
24+
<CarouselView.ItemTemplate>
25+
<DataTemplate
26+
x:DataType="{x:Null}">
27+
<Border BackgroundColor="Red"
28+
Stroke="Blue"
29+
StrokeShape="RoundRectangle 12"
30+
StrokeThickness="0">
31+
<Grid Margin="16"
32+
ColumnDefinitions="*,*"
33+
ColumnSpacing="15"
34+
RowDefinitions="*,*,36"
35+
RowSpacing="15">
36+
<VerticalStackLayout
37+
Grid.Row="0"
38+
Grid.ColumnSpan="2"
39+
VerticalOptions="Center">
40+
<Label FontSize="16"
41+
LineBreakMode="WordWrap"
42+
Text="DummyLabel"
43+
TextColor="#333333"
44+
VerticalOptions="Center"/>
45+
<Label FontFamily="Medium"
46+
FontSize="14"
47+
LineBreakMode="WordWrap"
48+
Text="DummyDesc"
49+
TextColor="#5F5E6A"/>
50+
</VerticalStackLayout>
51+
52+
<Border Grid.Row="1"
53+
Grid.Column="0"
54+
BackgroundColor="LightGray"
55+
HorizontalOptions="Start"
56+
StrokeShape="RoundRectangle 12"
57+
StrokeThickness="0"
58+
VerticalOptions="Center">
59+
<Label Grid.Column="1"
60+
FontFamily="Regular"
61+
FontSize="14"
62+
Margin="6"
63+
AutomationId="{Binding .}"
64+
Text="{Binding .}"
65+
TextColor="Black"
66+
VerticalOptions="Center"/>
67+
</Border>
68+
69+
<Border Grid.Row="1"
70+
Grid.Column="1"
71+
BackgroundColor="#e8fccf"
72+
HorizontalOptions="Center"
73+
StrokeShape="RoundRectangle 12"
74+
StrokeThickness="0"
75+
VerticalOptions="Center">
76+
<Label Grid.Column="1"
77+
FontFamily="Regular"
78+
FontSize="14"
79+
Margin="6"
80+
Text="{Binding .}"
81+
TextColor="#155d27"
82+
VerticalOptions="Center"/>
83+
</Border>
84+
85+
<Label Grid.Row="2"
86+
FontSize="24"
87+
HorizontalOptions="Start"
88+
Text="I am here"
89+
TextColor="Black"
90+
VerticalOptions="Center"/>
91+
92+
<Button Grid.Row="2"
93+
Grid.Column="1"
94+
BackgroundColor="White"
95+
BorderWidth="2"
96+
TextColor="Black"
97+
Text="Click me"
98+
VerticalOptions="Center"/>
99+
</Grid>
100+
</Border>
101+
</DataTemplate>
102+
</CarouselView.ItemTemplate>
103+
</CarouselView>
104+
</Grid>
105+
</ContentPage>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Maui.Controls.Sample.Issues
2+
{
3+
[Issue(IssueTracker.Github, 25192, "CarouselView Loop='False' renders incorrectly items", PlatformAffected.All)]
4+
public partial class Issue25192 : ContentPage
5+
{
6+
public Issue25192()
7+
{
8+
InitializeComponent();
9+
}
10+
}
11+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using NUnit.Framework;
2+
using UITest.Appium;
3+
using UITest.Core;
4+
5+
namespace Microsoft.Maui.TestCases.Tests.Issues
6+
{
7+
public class Issue25192 : _IssuesUITest
8+
{
9+
public Issue25192(TestDevice testDevice) : base(testDevice)
10+
{
11+
}
12+
13+
public override string Issue => "CarouselView Loop='False' renders incorrectly items";
14+
15+
[Test]
16+
[Category(UITestCategories.CarouselView)]
17+
public void CarouselViewShouldRenderCorrectly()
18+
{
19+
App.WaitForElement("Item1");
20+
VerifyScreenshot();
21+
}
22+
}
23+
}
8.94 KB
Loading
38.9 KB
Loading

0 commit comments

Comments
 (0)