dotnet / dotnet/maui

SafeAreaEdgeAndroid : safe zones not always respected when using custom controls ?

Open
#36,728 4 comments 1 reaction 0 assignees View on GitHub
area-safearea platform/android s/triaged s/verified t/bug
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 10h
Merged PRs (30d)
306

Description

### Description

I have a MAUI app that runs on Android.
I'm using an emulator to reproduce a user's bug (with a Pixel 10, Android 16, so I'm using a Pixel 9 emulator template with the latest available apis (37.1) and up-to-date stable MAUI install (dotnet 10).

When I navigate to a page (from the Flyout menu) that has a custom header (custom control), it seems that MAUI android struggles with the resize/relocation of the custom control (maybe a timing issue) and the custom header very often lands behind the Android Status bar.
I narrowed it down the the custom control, removing it from the pages and using the default Shell.NavBar does not have the same behavior and content is always presented correctly.

Here is a short video that demonstrates my current issue on a real app:
1. From a page (Flyout Shell), I go to one of the placeholder pages (Stats or Inscriptions)
2. When the page opens, the custom header is displayed correctly (all the pages uses the SafeAreaEdges = All)
3. Go to another page, the second placeholder for instance
4. When landing on the other page, this time the header is misplaced (albeit they are exactly the same page, just duplicated in memory)
5. Rotating the phone fixes the issue.

https://github.com/user-attachments/assets/60ffb66f-dfa9-48f8-82f3-cfade54037ae

So far, it has been fairly easy for me to reproduce the issue and it behaves like that on real hardware as well.
You'll notice that sometimes it's fine the first time I open a page, but navigating back to it after loading other pages (which is the current app behavior) will trigger the issue after one or 2 round trips.

I'll share the details of the placeholder page (xaml+xaml.cs) and the custom header control (see dedicated repro repository).
And here is a repro performed with a template Maui project.

https://github.com/user-attachments/assets/34329d41-8c6c-4b9f-919d-08dce6a71d45

Those files are enough to reproduce the issue:
Image
=> They are available in the linked Github repository: [MauiSafeAreaEdges-Android-BugRepro](https://github.com/bebenlebricolo/MauiSafeAreaEdges-Android-BugRepro)

This project was built from scratch, and I just pulled my crappy control and added the new test page in the Shell.

### Steps to Reproduce

See linked repository for repro materials.

## How to reproduce the bug
1. Open the solution (Visual Studio, Rider, VSCode ?) and build the project in Debug.
2. Then, launch (debug) the app on an Android Emulator (I used a Pixel 9 emulated device with Android Apis 37.1).

When the app launches, it displays the landing home page.

3.Go to the top left corner and open the Flyout menu, then go to the Test page.
4.Use the top left button (the ugly blue circle at the top left corner), this will reopen the flyout menu without the help of the default Shell navbar (this is intentional).
5.Click on Main Page and go back to the Test page, via the Flyout path.

After one or two round trips, the blue header of the TestPage should be placed at the very top of the screen, hidden behind the Android status bar!
That's the reproduction: the header has moved and buttons are now behing the Android Status bar.

Rotate the phone in landscape mode => header is reset to a properly working position.
Rotate back to the portrait mode => header is now at the right spot again.

### Link to public reproduction project repository

https://github.com/bebenlebricolo/MauiSafeAreaEdges-Android-BugRepro

### Version with bug

10.0.20

### Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI, No, this is something new

### Last version that worked well

Unknown/Other

### Affected platforms

Android

### Affected platform versions

Android with Apis 30 works fine, Android 11/12 should behave correctly as well.

### Did you find any workaround?

Rotating the phone is one solution.
In my use case, the header can be replaced by the default NavBar that I should restyle.
For some reason, it seems to appear on custom controls located near the top of the page.

Contributor guide

Open the contributing guide

Research direction

Start with the linked MauiSafeAreaEdges-Android-BugRepro project, especially the Test page, its XAML and code-behind, and the custom header control. Run it on an Android emulator, navigate between the Shell flyout pages, and observe the header after repeated round trips. Done means the custom header remains below the Android status bar without requiring device rotation.

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.