You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI中如何获取应用可用屏幕空间及系统状态栏、导航栏高度?

解决方案

一、Android平台下获取状态栏与导航栏高度

MAUI没有跨平台统一API获取系统栏高度,需通过平台特定代码实现:

1. 获取状态栏高度

在Android项目中添加如下方法:

using Android.Content;
using Android.Util;

public static int GetStatusBarHeight(Context context)
{
    int result = 0;
    int resourceId = context.Resources.GetIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0)
    {
        result = context.Resources.GetDimensionPixelSize(resourceId);
    }
    // 转换为MAUI设备独立单位(DP)
    return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, result, context.Resources.DisplayMetrics);
}

2. 获取导航栏高度

同样在Android项目中实现:

public static int GetNavigationBarHeight(Context context)
{
    int result = 0;
    int resourceId = context.Resources.GetIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0)
    {
        result = context.Resources.GetDimensionPixelSize(resourceId);
    }
    // 转换为MAUI设备独立单位(DP)
    return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, result, context.Resources.DisplayMetrics);
}

Android标准参考高度:

  • 状态栏:通常为24dp(厂商定制设备可能略有差异)
  • 导航栏:默认虚拟按键模式下为48dp,手势导航模式下高度会动态变化,需结合系统导航模式判断。

二、获取应用实际可用屏幕高度

直接获取MAUI窗口的可用区域是更高效的方式,无需单独计算系统栏:

1. 跨平台通用方式(推荐)

通过Application.Current.Windows获取当前窗口的Bounds属性,该值已自动排除系统栏占用空间:

var currentWindow = Application.Current?.Windows.FirstOrDefault();
if (currentWindow != null)
{
    // 应用可用区域的宽高(设备独立单位)
    double usableWidth = currentWindow.Bounds.Width;
    double usableHeight = currentWindow.Bounds.Height;
}

2. Android平台特定方式

通过原生Android API获取窗口可用区域:

using Android.App;
using Android.Views;
using Android.Util;

public static Rectangle GetUsableScreenArea(Activity activity)
{
    var windowMetrics = activity.WindowManager.CurrentWindowMetrics;
    var insets = windowMetrics.WindowInsets.GetInsetsIgnoringVisibility(WindowInsets.Type.SystemBars());
    
    // 计算可用区域的偏移与尺寸
    int leftInset = insets.Left;
    int topInset = insets.Top;
    int usableWidth = windowMetrics.Bounds.Width() - insets.Left - insets.Right;
    int usableHeight = windowMetrics.Bounds.Height() - insets.Top - insets.Bottom;
    
    // 转换为MAUI设备独立单位
    var metrics = activity.Resources.DisplayMetrics;
    return new Rectangle(
        TypedValue.ApplyDimension(ComplexUnitType.Dip, leftInset, metrics),
        TypedValue.ApplyDimension(ComplexUnitType.Dip, topInset, metrics),
        TypedValue.ApplyDimension(ComplexUnitType.Dip, usableWidth, metrics),
        TypedValue.ApplyDimension(ComplexUnitType.Dip, usableHeight, metrics)
    );
}

三、修正控件位置计算与可见性判断

结合可用区域,修正你的位置计算函数,并实现可见性判断:

public Point GetUsableScreenCoords(VisualElement view)
{
    var screenCoords = new Point(view.X, view.Y);
    var parent = view.Parent as VisualElement;
    while (parent != null)
    {
        screenCoords = screenCoords.Offset(parent.X, parent.Y);
        parent = parent.Parent as VisualElement;
    }
    return screenCoords;
}

public bool IsViewVisibleInUsableArea(VisualElement view)
{
    var currentWindow = Application.Current?.Windows.FirstOrDefault();
    if (currentWindow == null || view.Width <= 0 || view.Height <= 0)
        return false;
    
    var viewBounds = new Rectangle(GetUsableScreenCoords(view), new Size(view.Width, view.Height));
    var usableArea = currentWindow.Bounds;
    
    // 检查控件与可用区域是否存在交集
    return usableArea.IntersectsWith(viewBounds);
}

内容的提问来源于stack exchange,提问作者AndreasW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:47:47