-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Implement SafeAreaEdges property and per-edge safe area control for Android #31022
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
Implement SafeAreaEdges property and per-edge safe area control for Android #31022
Conversation
|
Thank you so much for this effort! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request implements a comprehensive safe area handling system for Android platform in .NET MAUI, introducing per-edge safe area control and keyboard awareness. The implementation adds a centralized SafeAreaHandler class to manage safe area insets consistently across different view types while optimizing performance through caching and hierarchy traversal optimizations.
- Introduces unified safe area handling with
SafeAreaHandlerclass for consistent behavior across ContentViewGroup and LayoutViewGroup - Adds per-edge safe area control through new
SafeAreaPaddingrecord andWindowInsetsExtensions - Integrates keyboard-aware layout adjustments that respond to IME visibility changes
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| SafeAreaPadding.cs | New record struct for representing safe area padding with conversion utilities |
| SafeAreaHandler.cs | Core safe area management class with caching, hierarchy checks, and window insets handling |
| MauiScrollView.cs | Minor addition of AndroidX.Core.View using statement and null check |
| LayoutViewGroup.cs | Integration of SafeAreaHandler with window insets listener setup and safe area adjustments |
| ContentViewGroup.cs | Integration of SafeAreaHandler with window insets listener setup and safe area adjustments |
Comments suppressed due to low confidence (2)
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the tests to validate the changes, right?
#30908
Could we expand it to support more edge cases? I would include more tests like:
SafeAreaBorderOrientationPortraitToLandscape- Tests orientation change from portrait to landscape, verifying that the safe area adapts, the border dimensions change, and insets adjust on notched devices.SafeAreaBorderOrientationLandscapeToPortrait- Tests orientation change from landscape to portrait, ensuring the safe area reverts correctly and border dimensions differ between orientations.SafeAreaBorderMultipleOrientationChanges- Tests multiple sequential orientation changes (portrait to landscape and back), verifying border visibility, positioning consistency within the same orientation (with tolerance), and overall stability.SafeAreaBorderSoftInputBehavior- Tests soft input (keyboard) behavior with bottom edge set to SoftInput, checking that the border shrinks when the keyboard appears and returns to original size after dismissal.SafeAreaBorderSoftInputWithOrientationChange- Tests soft input with orientation change (portrait to landscape) while keyboard is visible, ensuring the border maintains visibility and dimensions differ between orientations.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still need to review this a little bit deeper but I do still wonder about @albyrock87 's comment here
I wonder about the approach here with storing the safea area into separate handlers and then modifying the arrange pass.
In theory could we just have a global handler that sets the padding on the view?
Basically what I've done to fix the safearea on various views for edge to edge is just set the padding inside the windowinset listener
could we take the same approach here? Like, we just have a window listener applied to ContentViewGroup and LayoutViewGroup and then inside the "ApplyWindowLIstener" it extracts the safeareas and sets the padding on the views.
If the padding is set on the views than the measure and arrange passes will just work. The main reason we don't do this approach on iOS (AFAIK) is that iOS doesn't really have a concept of "padding" you can set on views, you always just fake the padding inside LayoutSubviews.
23cfd7d to
5977089
Compare
| Microsoft.Maui.LifecycleEvents.AndroidLifecycle.OnKeyMultiple | ||
| Microsoft.Maui.LifecycleEvents.AndroidLifecycle.OnKeyShortcut | ||
| Microsoft.Maui.LifecycleEvents.AndroidLifecycle.OnKeyUp | ||
| Microsoft.Maui.Platform.IHandleWindowInsets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep these internal for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, marked it as internal.
| /// Gets the shared GlobalWindowInsetListener instance for this activity. | ||
| /// This ensures all views use the same listener instance for coordinated inset management. | ||
| /// </summary> | ||
| public GlobalWindowInsetListener GlobalWindowInsetListener => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make this internal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PureWeen , Done, marked it as internal.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
/backport to release/10.0.1xx-rc2 |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
Started backporting to release/10.0.1xx-rc2: https://github.com/dotnet/maui/actions/runs/18048977023 |
Updated assertion message for clarity and added conditional compilation for return statement.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
Added comments regarding test behavior differences between headless and non-headless modes for Android.
|
/azp run |
|
/backport to release/10.0.1xx-rc2 |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
Started backporting to release/10.0.1xx-rc2: https://github.com/dotnet/maui/actions/runs/18051590261 |
Removed commented-out code regarding test behavior for headless vs non-headless view positioning. Updated test method for better clarity.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/backport to release/10.0.1xx-rc2 |
|
Started backporting to release/10.0.1xx-rc2: https://github.com/dotnet/maui/actions/runs/18052761878 |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/backport to release/10.0.1xx-rc2 |
|
Started backporting to release/10.0.1xx-rc2: https://github.com/dotnet/maui/actions/runs/18057314724 |
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description of Change
This pull request introduces a unified and optimized approach for handling safe area insets and keyboard visibility across Android platform views in the codebase. The changes add a new
SafeAreaHandlerclass, refactorContentViewGroupandLayoutViewGroupto use this handler, and implement supporting types and extension methods for safe area calculations. The main goal is to ensure consistent, performant, and keyboard-aware safe area handling for layouts, reducing repeated hierarchy traversals and improving maintainability.Safe Area Handling Improvements
SafeAreaHandlerclass (SafeAreaHandler.cs) to encapsulate shared logic for safe area and keyboard inset handling, including caching, hierarchy traversal optimizations, and a unified window insets listener.ContentViewGroupandLayoutViewGroupto instantiate and useSafeAreaHandler, including setup of window insets listeners and safe area adjustment logic in their constructors andOnLayoutmethods. [1] [2] [3] [4]Supporting Types and Extensions
SafeAreaPaddingrecord struct andWindowInsetsExtensionsstatic class for safe area and keyboard inset calculations, conversion, and rectangle adjustment.Dependency Updates
AndroidX.Core.Viewusing statements to affected files to support new window insets APIs. [1] [2]These changes collectively provide a robust foundation for safe area and keyboard-aware layout on Android, making it easier to maintain and extend in the future.
Issues Fixed
Fixes # https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2433909
Output
Android.mov