dotnet / dotnet/maui

[Android] On Android the HorizontalOptions for HorizontalStackLayout does not work

Open
#31,428 3 comments 0 reactions 1 assignee Claimed by @kubaflo View on GitHub
area-layout platform/android s/triaged s/verified t/bug
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 15h
Merged PRs (30d)
290

Description

### Description

When using a custom HorizontalWrapLayout element from the lesson on the site [learn.microsoft](https://learn.microsoft.com/ru-ru/dotnet/maui/user-interface/layouts/custom?view=net-maui-9.0) on Android devices, the property `HorizontalOptions="Center"` does not work.
### PC

Image

### Android

Image

Image

### Steps to Reproduce

1. Create MAUI project
2. Change MainPage.xaml to:
```C#
















```

3. Create a folder called "HorizontalWrapLayout" in the root of the solution.

Image

4. Create a class "HorizontalWrapLayout" in the folder.
```C#
using Microsoft.Maui.Layouts;
namespace MauiApp1.HorizontalWrapLayout
{
public class HorizontalWrapLayout : HorizontalStackLayout
{
protected override ILayoutManager CreateLayoutManager()
{
return new HorizontalWrapLayoutManager(this);
}
}
}
```
5. Create a class "HorizontalWrapLayoutManager" in the folder.
```C#
using Microsoft.Maui.Layouts;

namespace MauiApp1.HorizontalWrapLayout
{
public class HorizontalWrapLayoutManager : HorizontalStackLayoutManager
{
HorizontalWrapLayout _layout;

public HorizontalWrapLayoutManager(HorizontalWrapLayout horizontalWrapLayout) : base(horizontalWrapLayout)
{
_layout = horizontalWrapLayout;
}

public override Size Measure(double widthConstraint, double heightConstraint)
{
var padding = _layout.Padding;

widthConstraint -= padding.HorizontalThickness;

double currentRowWidth = 0;
double currentRowHeight = 0;
double totalWidth = 0;
double totalHeight = 0;

for (int n = 0; n < _layout.Count; n++)
{
var child = _layout[n];
if (child.Visibility == Visibility.Collapsed)
{
continue;
}

var measure = child.Measure(double.PositiveInfinity, heightConstraint);

// Will adding this IView put us past the edge?
if (currentRowWidth + measure.Width > widthConstraint)
{
// Keep track of the width so far
totalWidth = Math.Max(totalWidth, currentRowWidth);
totalHeight += currentRowHeight;

// Account for spacing
totalHeight += _layout.Spacing;

// Start over at 0
currentRowWidth = 0;
currentRowHeight = measure.Height;
}
currentRowWidth += measure.Width;
currentRowHeight = Math.Max(currentRowHeight, measure.Height);

if (n < _layout.Count - 1)
{
currentRowWidth += _layout.Spacing;
}
}

// Account for the last row
totalWidth = Math.Max(totalWidth, currentRowWidth);
totalHeight += currentRowHeight;

// Account for padding
totalWidth += padding.HorizontalThickness;
totalHeight += padding.VerticalThickness;

// Ensure that the total size of the layout fits within its constraints
var finalWidth = ResolveConstraints(widthConstraint, Stack.Width, totalWidth, Stack.MinimumWidth, Stack.MaximumWidth);
var finalHeight = ResolveConstraints(heightConstraint, Stack.Height, totalHeight, Stack.MinimumHeight, Stack.MaximumHeight);

return new Size(finalWidth, finalHeight);
}

public override Size ArrangeChildren(Rect bounds)
{
var padding = Stack.Padding;
double top = padding.Top + bounds.Top;
double left = padding.Left + bounds.Left;

double currentRowTop = top;
double currentX = left;
double currentRowHeight = 0;

double maxStackWidth = currentX;

for (int n = 0; n < _layout.Count; n++)
{
var child = _layout[n];
if (child.Visibility == Visibility.Collapsed)
{
continue;
}

if (currentX + child.DesiredSize.Width > bounds.Right)
{
// Keep track of our maximum width so far
maxStackWidth = Math.Max(maxStackWidth, currentX);

// Move down to the next row
currentX = left;
currentRowTop += currentRowHeight + _layout.Spacing;
currentRowHeight = 0;
}

var destination = new Rect(currentX, currentRowTop, child.DesiredSize.Width, child.DesiredSize.Height);
child.Arrange(destination);

currentX += destination.Width + _layout.Spacing;
currentRowHeight = Math.Max(currentRowHeight, destination.Height);
}

var actual = new Size(maxStackWidth, currentRowTop + currentRowHeight);

// Adjust the size if the layout is set to fill its container
return actual.AdjustForFill(bounds, Stack);
}
}
}
```
6. Run the application on Windows and Android.
7. Compare.

### Link to public reproduction project repository

_No response_

### Version with bug

9.0.30 SR3

### Is this a regression from previous behavior?

Not sure, did not test other versions

### Last version that worked well

Unknown/Other

### Affected platforms

Android

### Affected platform versions

Android 13, Android 16

### Did you find any workaround?

_No response_

### Relevant log output

```shell

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.