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
相关产品推荐
相关产品推荐

