dotnet / dotnet/maui

[Android] Layout changes are not rendered without triggering a render cycle via interaction with UI

Open
#10,539 6 comments 3 reactions 0 assignees 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

I have a layout that I am optimizing for Portrait and Landscape modes respectively.

When I rotate the device, I change some layout values, such as the `HorizontalOptions` and `VerticalOptions` of certain Views that I would like to reposition in response to the size change for which I have an overide of `OnSizeAllocated()`. I am using the **VisualStateManager** to update the layout, but I've encountered exactly the same issue when I manually set the values in the code-behind or via bindings.

The problem is that there seems to be a render cycle missing after updating the layout. The changes only get applied when I add some UI interaction, such as a button press that triggers a _PropertyChanged_ event on some property. This problem applies to all kinds of Views, such as Grids, StackLayouts, Labels and Buttons.

In the following example to reproduce the issue, there is a button that is centered at the bottom in Portrait mode and moved to the right hand-side when going into Landscape mode. The button only changes its position after pressing it instead of updating immediately:

**XAML**
```xml




<Setter Property="Margin" Value="20" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Portrait">
<VisualState.Setters>
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="End" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Landscape">
<VisualState.Setters>
<Setter Property="HorizontalOptions" Value="End" />
<Setter Property="VerticalOptions" Value="Center" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>


```

**Code-behind**
```c#
namespace MauiViewUpdateBug;

public partial class MainPage : ContentPage
{
public int Clicks { get; set; }

public MainPage()
{
InitializeComponent();
BindingContext = this;
}

protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);

VisualStateManager.GoToState(MyButton, width > height ? "Landscape" : "Portrait");
}

private void MyButton_OnClicked(object sender, EventArgs e)
{
Clicks++;
OnPropertyChanged(nameof(Clicks));
}
}
```

**Note: This only occurs on Android, on iOS it works fine. This happens with real devices, not tested with emulators. I can reproduce this on Samsung S22 and S10 devices (at least).**

### Steps to Reproduce

1. Create a new MAUI project
2. Add the XAML and Code-behind like in the sample
3. Run the App on an Android device
4. Rotate the Device

Expected Behavior: The Button moves to the right in Landscape mode
Actual Behavior: The Button stays where it is and only updates its position after pressing it

### Link to public reproduction project repository

https://github.com/ewerspej/dotnet-maui-bug-view-update

### Version with bug

7.0.0-rc.1.22426.10

### Last version that worked well

Unknown/Other

### Affected platforms

Android

### Affected platform versions

Android 12.0

### Did you find any workaround?

No

### Relevant log output

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by running the provided XAML and code-behind reproduction on a physical Android device and rotate it between portrait and landscape. Trace the VisualStateManager state change from OnSizeAllocated and compare it with the later update caused by the button click; done means the button repositions immediately after rotation without UI interaction.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, csharp
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.