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

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

【问题讨论】:

    标签: xamarin.forms size statusbar


    【解决方案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;
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-23
        • 1970-01-01
        • 2011-04-22
        • 2013-12-15
        • 1970-01-01
        • 2018-08-16
        • 2018-05-21
        • 2015-06-06
        相关资源
        最近更新 更多