Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Flex Layouts #25036

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 26 additions & 29 deletions src/Controls/src/Core/Layout/FlexLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,42 +491,39 @@ void AddFlexItem(int index, IView child)
_viewInfo.Add(child, new FlexInfo());
}

var item = (child as FlexLayout)?._root ?? new Flex.Item();
var item = new Flex.Item();
InitItemProperties(child, item);
if (child is not FlexLayout)
item.SelfSizing = (Flex.Item it, ref float w, ref float h) =>
{
item.SelfSizing = (Flex.Item it, ref float w, ref float h) =>
{
Size request;

if (InMeasureMode)
{
var sizeConstraints = item.GetConstraints();

sizeConstraints.Width = (InMeasureMode && sizeConstraints.Width == 0) ? double.PositiveInfinity : sizeConstraints.Width;
sizeConstraints.Height = (InMeasureMode && sizeConstraints.Height == 0) ? double.PositiveInfinity : sizeConstraints.Height;
Size request;

if (child is Image)
{
// This is a hack to get FlexLayout to behave like it did in Forms
// Forms always did its initial image measure unconstrained, which would return
// the intrinsic size of the image (no scaling or aspect ratio adjustments)
if (InMeasureMode)
{
var sizeConstraints = item.GetConstraints();

sizeConstraints.Width = double.PositiveInfinity;
sizeConstraints.Height = double.PositiveInfinity;
}
sizeConstraints.Width = (InMeasureMode && sizeConstraints.Width == 0) ? double.PositiveInfinity : sizeConstraints.Width;
sizeConstraints.Height = (InMeasureMode && sizeConstraints.Height == 0) ? double.PositiveInfinity : sizeConstraints.Height;

request = child.Measure(sizeConstraints.Width, sizeConstraints.Height);
}
else
if (child is Image)
{
// Arrange pass, do not ever run a measure here!
request = child.DesiredSize;
// This is a hack to get FlexLayout to behave like it did in Forms
// Forms always did its initial image measure unconstrained, which would return
// the intrinsic size of the image (no scaling or aspect ratio adjustments)

sizeConstraints.Width = double.PositiveInfinity;
sizeConstraints.Height = double.PositiveInfinity;
}
w = (float)request.Width;
h = (float)request.Height;
};
}

request = child.Measure(sizeConstraints.Width, sizeConstraints.Height);
}
else
{
// Arrange pass, do not ever run a measure here!
request = child.DesiredSize;
}
w = (float)request.Width;
h = (float)request.Height;
};

_root.InsertAt(index, item);
SetFlexItem(child, item);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
111 changes: 111 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue20461.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?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.Issue20461"
xmlns:local="clr-namespace:Maui.Controls.Sample.Issues">
<Grid RowDefinitions="Auto,*">

<FlexLayout Direction="Row"
Grid.Row="0"
BackgroundColor="Black"
HeightRequest="48"
AlignItems="Center"
JustifyContent="Start"
HorizontalOptions="Start"
VerticalOptions="Start">
<!-- Child FlexLayout on the left with a 24x24 pixel Rectangle inside -->
<FlexLayout Direction="Row"
AlignItems="Center"
JustifyContent="Start"
BackgroundColor="LightBlue"
FlexLayout.Basis="48"
HeightRequest="24"
FlexLayout.Grow="1">
<Rectangle WidthRequest="24"
HeightRequest="24"
Fill="Blue"/>
</FlexLayout>

<!-- Child FlexLayout on the right with 3 FlexLayouts inside it -->
<FlexLayout Direction="Row"
VerticalOptions="Start"
AlignItems="Start"
JustifyContent="SpaceBetween"
HeightRequest="24"
BackgroundColor="Grey"
FlexLayout.Basis="144">
<!-- Each of these FlexLayouts has a 24x24 pixel Rectangle inside -->
<FlexLayout Direction="Row"
AlignItems="Center"
VerticalOptions="Start"
JustifyContent="Center"
BackgroundColor="Pink"
HeightRequest="24"
FlexLayout.Basis="48">
<Rectangle WidthRequest="24"
HeightRequest="24"
Fill="Red"/>
</FlexLayout>
<FlexLayout Direction="Row"
AlignItems="Center"
VerticalOptions="Start"
JustifyContent="Center"
BackgroundColor="LightGreen"
HeightRequest="24"
FlexLayout.Basis="48">
<Rectangle WidthRequest="24"
HeightRequest="24"
Fill="Green"/>
</FlexLayout>
<FlexLayout Direction="Row"
AlignItems="Center"
VerticalOptions="Start"
JustifyContent="Center"
BackgroundColor="LightYellow"
HeightRequest="24"
FlexLayout.Basis="48">
<Rectangle WidthRequest="24"
HeightRequest="24"
Fill="Yellow"/>
</FlexLayout>
</FlexLayout>
</FlexLayout>

<FlexLayout Grid.Row="1"
Direction="Column"
BackgroundColor="LightBlue"
Wrap="Wrap">
<Label Text="Parent FlexLayout - First Element"/>
<FlexLayout Direction="Row"
BackgroundColor="Yellow"
JustifyContent="SpaceBetween"
Wrap="Wrap"
AlignItems="Center">
<Label Text="Nested FlexLayout - First Element"/>
<Label Text="Nested FlexLayout - Second Element"/>
<Image Source="groceries.png"
WidthRequest="30"
HeightRequest="30"
BackgroundColor="LightBlue"
AutomationId="imageInNestedLayout"/>
<ImageButton Source="groceries.png"
WidthRequest="30"
HeightRequest="30"
CornerRadius="15"
BackgroundColor="Red"
AutomationId="imageButtonInNestedLayout"/>
<Label Text="Nested FlexLayout - Third Element"/>
</FlexLayout>

<ImageButton Source="groceries.png"
WidthRequest="100"
HeightRequest="100"
CornerRadius="50"
BackgroundColor="Red"
AutomationId="imageButtonInParentLayout"/>

<Label Text="Parent FlexLayout - Second Element"/>
</FlexLayout>
</Grid>
</ContentPage>
13 changes: 13 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue20461.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.Maui.Controls;

namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 20461, "Nested FlexLayouts", PlatformAffected.All)]
public partial class Issue20461 : ContentPage
{
public Issue20461()
{
InitializeComponent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues
{
public class Issue20461 : _IssuesUITest
{
public Issue20461(TestDevice testDevice) : base(testDevice)
{
}

public override string Issue => "Nested FlexLayouts";

[Test]
[Category(UITestCategories.Layout)]
public void NestedFlexLayoutShouldRenderCorrectly()
{
App.WaitForElement("imageInNestedLayout");
App.WaitForElement("imageButtonInNestedLayout");
VerifyScreenshot();
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading