Fixed CarouselView Loop="False" rendering items incorrectly - test fix (#25924)

* Fixed CarouselView Loop="False" rendering items incorrectly

* Added snapshots

* Update CarouselViewShouldRenderCorrectly.png
This commit is contained in:
Jakub Florkowski 2024-11-19 17:11:04 +01:00 коммит произвёл GitHub
Родитель 800a8a010b
Коммит 6b00a272b3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 172 добавлений и 37 удалений

Просмотреть файл

@ -571,46 +571,42 @@ namespace Microsoft.Maui.Controls.Handlers.Items
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (Carousel.Loop)
// If the height or width are unbounded and the user is set to
// Loop then we can't just do an infinite measure.
// Looping works by setting item count to 16384 so if the
// CarV has infinite room it'll generate all 16384 items.
// This code forces the adapter to just measure the first item
// And then that measure is used for the WxH of the CarouselView
// I found that "AtMost" also causes this behavior so
// that's why I'm turning "AtMost" into "Exactly"
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.AtMost)
{
// If the height or width are unbounded and the user is set to
// Loop then we can't just do an infinite measure.
// Looping works by setting item count to 16384 so if the
// CarV has infinite room it'll generate all 16384 items.
// This code forces the adapter to just measure the first item
// And then that measure is used for the WxH of the CarouselView
// I found that "AtMost" also causes this behavior so
// that's why I'm turning "AtMost" into "Exactly"
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.AtMost)
{
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(widthMeasureSpec.GetSize());
}
if (MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.AtMost)
{
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(heightMeasureSpec.GetSize());
}
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.Unspecified ||
MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.Unspecified)
{
if (ItemsViewAdapter.ItemCount > 0)
{
// Retrieve the first item of the CarouselView and measure it
// This is what we'll use for the CarV WxH if the requested measure
// is for an infinite amount of space
var viewType = ItemsViewAdapter.GetItemViewType(0);
var viewHolder = (ViewHolder)ItemsViewAdapter.CreateViewHolder(this, viewType);
ItemsViewAdapter.BindViewHolder(viewHolder, 0);
viewHolder.ItemView.Measure(widthMeasureSpec, heightMeasureSpec);
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredWidth);
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredHeight);
}
}
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(widthMeasureSpec.GetSize());
}
if (MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.AtMost)
{
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(heightMeasureSpec.GetSize());
}
if (MeasureSpec.GetMode(widthMeasureSpec) == MeasureSpecMode.Unspecified ||
MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.Unspecified)
{
if (ItemsViewAdapter.ItemCount > 0)
{
// Retrieve the first item of the CarouselView and measure it
// This is what we'll use for the CarV WxH if the requested measure
// is for an infinite amount of space
var viewType = ItemsViewAdapter.GetItemViewType(0);
var viewHolder = (ViewHolder)ItemsViewAdapter.CreateViewHolder(this, viewType);
ItemsViewAdapter.BindViewHolder(viewHolder, 0);
viewHolder.ItemView.Measure(widthMeasureSpec, heightMeasureSpec);
widthMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredWidth);
heightMeasureSpec = MeasureSpecMode.Exactly.MakeMeasureSpec(viewHolder.ItemView.MeasuredHeight);
}
}
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 35 KiB

Просмотреть файл

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue25192">
<Grid>
<CarouselView Margin="2,9,2,20"
HeightRequest="180"
Loop="False"
PeekAreaInsets="20"
VerticalOptions="End">
<CarouselView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Item1</x:String>
<x:String>Item2</x:String>
<x:String>Item3</x:String>
</x:Array>
</CarouselView.ItemsSource>
<CarouselView.ItemsLayout>
<LinearItemsLayout ItemSpacing="5"
Orientation="Horizontal"
SnapPointsAlignment="Center"
SnapPointsType="MandatorySingle"/>
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate
x:DataType="{x:Null}">
<Border BackgroundColor="Red"
Stroke="Blue"
StrokeShape="RoundRectangle 12"
StrokeThickness="0">
<Grid Margin="16"
ColumnDefinitions="*,*"
ColumnSpacing="15"
RowDefinitions="*,*,36"
RowSpacing="15">
<VerticalStackLayout
Grid.Row="0"
Grid.ColumnSpan="2"
VerticalOptions="Center">
<Label FontSize="16"
LineBreakMode="WordWrap"
Text="DummyLabel"
TextColor="#333333"
VerticalOptions="Center"/>
<Label FontFamily="Medium"
FontSize="14"
LineBreakMode="WordWrap"
Text="DummyDesc"
TextColor="#5F5E6A"/>
</VerticalStackLayout>
<Border Grid.Row="1"
Grid.Column="0"
BackgroundColor="LightGray"
HorizontalOptions="Start"
StrokeShape="RoundRectangle 12"
StrokeThickness="0"
VerticalOptions="Center">
<Label Grid.Column="1"
FontFamily="Regular"
FontSize="14"
Margin="6"
AutomationId="{Binding .}"
Text="{Binding .}"
TextColor="Black"
VerticalOptions="Center"/>
</Border>
<Border Grid.Row="1"
Grid.Column="1"
BackgroundColor="#e8fccf"
HorizontalOptions="Center"
StrokeShape="RoundRectangle 12"
StrokeThickness="0"
VerticalOptions="Center">
<Label Grid.Column="1"
FontFamily="Regular"
FontSize="14"
Margin="6"
Text="{Binding .}"
TextColor="#155d27"
VerticalOptions="Center"/>
</Border>
<Label Grid.Row="2"
FontSize="24"
HorizontalOptions="Start"
Text="I am here"
TextColor="Black"
VerticalOptions="Center"/>
<Button Grid.Row="2"
Grid.Column="1"
BackgroundColor="White"
BorderWidth="2"
TextColor="Black"
Text="Click me"
VerticalOptions="Center"/>
</Grid>
</Border>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</Grid>
</ContentPage>

Просмотреть файл

@ -0,0 +1,11 @@
namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 25192, "CarouselView Loop='False' renders incorrectly items", PlatformAffected.All)]
public partial class Issue25192 : ContentPage
{
public Issue25192()
{
InitializeComponent();
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;
namespace Microsoft.Maui.TestCases.Tests.Issues
{
public class Issue25192 : _IssuesUITest
{
public Issue25192(TestDevice testDevice) : base(testDevice)
{
}
public override string Issue => "CarouselView Loop='False' renders incorrectly items";
[Test]
[Category(UITestCategories.CarouselView)]
public void CarouselViewShouldRenderCorrectly()
{
App.WaitForElement("Item1");
VerifyScreenshot();
}
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 39 KiB