如何在 xamarin.forms 中获取状态栏高度?

Posted

技术标签:

【中文标题】如何在 xamarin.forms 中获取状态栏高度?【英文标题】:how can i get status bar height in xamarin.forms? 【发布时间】:2018-06-24 20:31:18 【问题描述】:

我正在尝试在我的应用程序中获取状态/操作栏高度。 我得到了一些我们如何在原生 android 中获得它的方法。 我们可以在 xamarin.forms 中获取状态/操作栏高度吗?如果是,那么如何? 如果有人对此有所了解,请提供帮助。

【问题讨论】:

【参考方案1】:

您可以通过创建自己的依赖服务来做到这一点。 (https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/dependency-service/introduction/)

在您的共享代码中,创建一个接口,例如 IStatusBar:

public interface IStatusBar
    
        int GetHeight();
    

为 Android 平台添加实现:

[assembly: Dependency(typeof(StatusBar))]
namespace StatusBarApp.Droid

    class StatusBar : IStatusBar
    
        public static Activity Activity  get; set; 

        public int GetHeight()
        
            int statusBarHeight = -1;
            int resourceId = Activity.Resources.GetIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0)
            
                statusBarHeight = Activity.Resources.GetDimensionPixelSize(resourceId);
            
            return statusBarHeight;
        
    

Activity 属性是从 MainActivity.cs 设置的:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    
        protected override void OnCreate(Bundle bundle)
        
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);

            StatusBar.Activity = this;

            LoadApplication(new App());
        
    

这是您从共享代码中调用实现的方式:

int statusBarHeight = DependencyService.Get<IStatusBar>().GetHeight();

ios平台的实现:

[assembly: Dependency(typeof(StatusBar))]
namespace StatusBarApp.iOS

    class StatusBar : IStatusBar
    
        public int GetHeight()
        
            return (int)UIApplication.SharedApplication.StatusBarFrame.Height;
        
    

【讨论】:

非常感谢您。我也在尝试,但不知道活动,所以想知道 ant resourses.u 救了我。 寻求更多帮助。我无法找到 ios。如果你完成了,你能分享 ios 依赖吗? 我没有,但我实现了。 我已经厌倦了这个。但我认为它没有提供正确的价值。就像 ipad 中的 m geeting 20。但状态栏似乎大于 20。请检查我更新的图像 StatusBar 是 NavigationBar 上方的细条,在 ios 上为 20 像素。所以你需要在这两者之间求和。您可以从 NavigationController.NavigationBar.Frame.Height 获取 navigationBar 高度。【参考方案2】:

此页面上的其他答案对我不起作用。他们返回的值比实际状态栏小约 8 DP,导致我的所有计算都关闭。

这是一个有效的纯 Xamarin Forms 解决方案:

// Tested only in Android
private double NavbarHeight => 
    Application.Current.MainPage is NavigationPage navPage && navPage.CurrentPage != null
    ? navPage.Height - navPage.CurrentPage.Height
    : 0;

不幸的是,这依赖于您的所有页面都扩展到其完整的父容器的假设,这并不总是正确的。

它还返回 DP 中的高度。如果您想要以像素为单位的高度,请乘以DeviceDisplay.MainDisplayInfo.Density

【讨论】:

@DavidClarke 您建议的更改会改变行为,因为它不会检查 CurrentPage 是否为空 好点,现在修复【参考方案3】:

通用代码(在 App.xaml.cs 中)

public static int StatusBarHeight get; set;

Android 部分(在 MainActivity.cs 中,在 OnCreate 方法中)

int resourceId = Resources.GetIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0)

    App.StatusBarHeight = (int)(Resources.GetDimensionPixelSize(resourceId) / Resources.DisplayMetrics.Density);

iOS 部分(在 AppDelegate.cs 中,在 FinishedLaunching 方法中)

App.StatusBarHeight = (int)UIApplication.SharedApplication.StatusBarFrame.Height;

所以 App.StatusBarHeight 会在应用启动时被初始化,然后你就可以在通用代码的任何地方使用它。

【讨论】:

【参考方案4】:

我使用了这样的依赖服务:

using System;
using System.IO;
using System.Threading.Tasks;
using Android.Content;
using Android.Content.Res;
using ProTrain.Droid.DependencyServices;
using ProTrain.Interfaces;

[assembly: Xamarin.Forms.Dependency(typeof(PlatformStuff))]
namespace MyApp.Droid.DependencyServices

    public class PlatformStuff : IPlatformStuff
    
        internal static Func<Context> GetContext  get; set;                         

        public int GetToolbarSize()
        
            var Context = GetContext();
            TypedArray styledAttributes = Context.Theme.ObtainStyledAttributes(
                new int[]  Android.Resource.Attribute.ActionBarSize );
            var actionbar = (int)styledAttributes.GetDimension(0, 0);
            styledAttributes.Recycle();
            return actionbar;
        
    

然后在 mainactivity 中设置上下文:

protected override void OnCreate(Bundle bundle)

    base.OnCreate(bundle);
    PlatformStuff.GetContext = () => this;
...

【讨论】:

以上是关于如何在 xamarin.forms 中获取状态栏高度?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xamarin Forms 中获取设备的 GPS 位置?

如何在 Xamarin.Forms.Map 中获取当前位置或移动到当前位置

Xamarin.Forms如何获取当前登录用户的Id等信息?

Xamarin.Forms (UWP) - 如何获取 WebView 的 DOM 作为 HTML 字符串?

Xamarin.Forms.Shell:如何获取底部 TabBar 高度?

在 Xamarin.Forms 中获取图像或 ImageSource 的字节 [] / 流?