Share via

MAUI .NET 10 - SafeAreaEdges get actual thickness values

Sebastian Kruse 1 Reputation point
2026-04-20T14:33:17.2566667+00:00

Is there a way to get the actual thickness values from SafeAreaEdges? I want to set my page to SafeAreaEdges.None but at the same time offset some controls if there is a safe area available. I know how todo it on iOS but not sure how to use it on Android. And no, I cannot wrap these elements in a Grid to apply the SafeAreaEdges.Container. One example: I want my collection view to display itself with SafeAreaEdges.None. But in the group header, I want to apply the safe area. That does not work as far as my testing goes.

Developer technologies | .NET | .NET MAUI
0 comments No comments

2 answers

Sort by: Most helpful
  1. Nancy Vo (WICLOUD CORPORATION) 3,465 Reputation points Microsoft External Staff Moderator
    2026-04-21T03:40:33.9033333+00:00

    Hello @Sebastian Kruse ,

    Thanks for your question.

    When you set SafeAreaEdges on a view inside a CollectionView.GroupHeaderTemplate, it gets ignored. This is because SafeAreaEdges is only processed at the Page level or direct layout children, not inside DataTemplate items rendered by a CollectionView.

    Since you already know iOS, I'll focus on Android. I recommend some following steps:

    1. Step 1: Create a shared interface
    public interface ISafeAreaService
    {
        Thickness GetSafeAreaInsets();
    }
    
    1. Step 2: Android implementation
    // Platforms/Android/SafeAreaService.cs
    using AndroidX.Core.View;
    using Microsoft.Maui.Platform;
    
    public class SafeAreaService : ISafeAreaService
    {
        public Thickness GetSafeAreaInsets()
        {
            var activity = Platform.CurrentActivity;
            if (activity == null) return new Thickness(0);
    
            var decorView = activity.Window?.DecorView;
            if (decorView == null) return new Thickness(0);
    
            var insets = ViewCompat.GetRootWindowInsets(decorView);
            if (insets == null) return new Thickness(0);
    
            var sysBars = insets.GetInsets(WindowInsetsCompat.Type.SystemBars());
    
            var cutout       = insets.DisplayCutout;
            int cutoutTop    = cutout?.SafeInsetTop    ?? 0;
            int cutoutBottom = cutout?.SafeInsetBottom ?? 0;
            int cutoutLeft   = cutout?.SafeInsetLeft   ?? 0;
            int cutoutRight  = cutout?.SafeInsetRight  ?? 0;
    
            float density = activity.Resources.DisplayMetrics.Density;
    
            return new Thickness(
                Math.Max(sysBars.Left,   cutoutLeft)   / density,
                Math.Max(sysBars.Top,    cutoutTop)    / density,
                Math.Max(sysBars.Right,  cutoutRight)  / density,
                Math.Max(sysBars.Bottom, cutoutBottom) / density
            );
        }
    }
    
    1. Step 3: Register in MauiProgram.cs
    builder.Services.AddSingleton<ISafeAreaService, SafeAreaService>();
    
    1. Step 4: Use in your page and apply to group header
    public partial class MyPage : ContentPage
    {
        private readonly ISafeAreaService _safeAreaService;
    
        public MyPage(ISafeAreaService safeAreaService)
        {
            InitializeComponent();
            _safeAreaService = safeAreaService;
        }
    
        protected override void OnAppearing()
        {
            base.OnAppearing();
    
            var insets = _safeAreaService.GetSafeAreaInsets();
    
            MyViewModel.GroupHeaderPadding = new Thickness(
                insets.Left,
                insets.Top,
                insets.Right,
                0
            );
        }
    }
    
    <ContentPage SafeAreaEdges="None">
        <CollectionView ItemsSource="{Binding GroupedItems}"
                        IsGrouped="True">
    
            <CollectionView.GroupHeaderTemplate>
                <DataTemplate>
                    <Grid Padding="{Binding Source={RelativeSource AncestorType={x:Type vm:MyViewModel}},
                                            Path=GroupHeaderPadding}">
                        <Label Text="{Binding GroupName}"
                               FontSize="18"
                               FontAttributes="Bold"/>
                    </Grid>
                </DataTemplate>
            </CollectionView.GroupHeaderTemplate>
    
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Label Text="{Binding Title}"/>
                </DataTemplate>
            </CollectionView.ItemTemplate>
    
        </CollectionView>
    </ContentPage>
    

    Note: it's better to read insets in OnAppearing() and test on a real device

    I hope this addresses your question. If this response was helpful, please consider following the guidance to provide feedback.


  2. Q&A Assist
    2026-04-20T14:33:43.5966667+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    On .NET MAUI .NET 10, SafeAreaEdges itself is just a flag that controls automatic padding; it doesn’t expose the actual inset values. To get the real safe area thickness and then apply custom offsets, use the platform API that returns the insets and combine it with SafeAreaEdges=None.

    On iOS, use the iOS-specific extension to read the current safe area insets at runtime:

    using Microsoft.Maui.Controls.PlatformConfiguration;
    using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
    
    // Inside a ContentPage
    protected override void OnAppearing()
    {
        base.OnAppearing();
    
        // This returns a Microsoft.Maui.Thickness
        var insets = this.On<iOS>().SafeAreaInsets();
    
        // Example: manually offset a layout using the insets
        MyRootLayout.Padding = new Thickness(
            insets.Left,
            insets.Top,
            insets.Right,
            insets.Bottom);
    }
    

    You can still keep the page edge-to-edge:

    <ContentPage
        xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="MyPage"
        SafeAreaEdges="None">
        <!-- content -->
    </ContentPage>
    

    Then, based on the insets value, selectively add padding or margins to specific controls instead of the whole page.

    For Android, there is no SafeAreaInsets() equivalent in the provided context. On Android, SafeAreaEdges controls how MAUI applies padding relative to system bars, but the actual inset values are not exposed via the same API in this documentation. The supported pattern in the context is:

    • Use SafeAreaEdges on pages/layouts/controls to let MAUI handle insets automatically when possible.
    • For iOS-only fine‑grained control, read insets via On<iOS>().SafeAreaInsets() and apply manual padding.

    So for a cross‑platform approach where the page is edge‑to‑edge but some controls respect safe areas:

    1. Set the page to edge‑to‑edge:
         <ContentPage SafeAreaEdges="None">
             <Grid x:Name="MainGrid">
                 <!-- controls -->
             </Grid>
         </ContentPage>
      
    2. On iOS, read the insets and apply them to the specific controls or container:
         protected override void OnAppearing()
         {
             base.OnAppearing();
         
             var insets = this.On<iOS>().SafeAreaInsets();
             HeaderView.Margin = new Thickness(insets.Left, insets.Top, insets.Right, 0);
             FooterView.Margin = new Thickness(insets.Left, 0, insets.Right, insets.Bottom);
         }
      

    On Android, rely on SafeAreaEdges (for example, put the control that should avoid bars/notch in a layout with SafeAreaEdges="Container") rather than reading raw inset values, as no API for that is shown in the current documentation.


    References:

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.