Xamarin.Forms.Shell:如何获取底部TabBar的高度?
Xamarin.Forms.Shell: how to get the bottom TabBar height?
我在使用默认底部 TabBar
开发 Xamarin.Forms.Shell 应用程序,我需要知道 TabBar
height 调整一些项目。
我找到了在两个平台 上获得 StatusBar
高度 的方法,但我没有找到 的解决方案=11=].
可能吗?我只发现有关更改 Stack 上的 TabBar 高度的请求...
据我所知,在 Xamarin.Forms 中(还?)不可能检索到 TabBar
Height
,所以您可能需要根据 Platform 收集该信息。然后,利用 DependencyService
,您可以从 Xamarin.Forms 共享代码中获取该信息。那么,让我们来看看如何去做:
iOS
对于iOS,已经有像这样的答案发布来解释如何做到这一点。
Android
对于Android,您可以按如下方式检索TabBar高度
- 为依赖项
创建接口
注意:iOS部分也应该使用这个接口;)
namespace Tabbarheight
{
public interface IDisplayHeights
{
float GetTabBarHeight();
}
}
- 在 Android 中创建一个实现该接口的 class 和 returns 所需的值
(感谢@LucasZhang-MSFT 提供标识符字符串!)
using Android.App;
using Tabbarheight.Droid;
using Xamarin.Forms;
[assembly: Dependency(typeof(AndroidDisplayHeights))]
namespace Tabbarheight.Droid
{
class AndroidDisplayHeights : IDisplayHeights
{
public static Activity Activity { get; set; }
public float GetTabBarHeight()
{
int resourceId = Activity.Resources.GetIdentifier("design_bottom_navigation_height", "dimen", Activity.PackageName);
int height = 0;
if (resourceId > 0)
{
height = (int)(Activity.Resources.GetDimensionPixelSize(resourceId) / Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density);
}
return height;
}
}
}
其中Activity
由MainActivity.cs设置如下
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
AndroidDisplayHeights.Activity = this;
LoadApplication(new App());
}
- 最后,您可以按如下方式使用它
public AboutPage()
{
InitializeComponent();
SizeChanged += (s, a) =>
{
label.HeightRequest = DependencyService.Get<IDisplayHeights>().GetTabBarHeight();
label.BackgroundColor = Color.Red;
};
}
在上面的解决方案中,我定义了一个 Label
(标签)只是为了尝试通过设置 [=19= 来证明获得的 TabBar
的 Height
值的准确性]的身高。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Tabbarheight.Views.AboutPage"
xmlns:vm="clr-namespace:Tabbarheight.ViewModels"
Title="{Binding Title}">
<StackLayout>
<Label x:Name="label">
<Label.Text>
<x:String>
Hola mundo
</x:String>
</Label.Text>
</Label>
</StackLayout>
</ContentPage>
我这边的标签是这样的:
我们可以使用Custom Renderer
获取高度
在 AppShell 中
public partial class AppShell : Xamarin.Forms.Shell
{
public static double TabHeight { get; set; }
//...
}
在iOS项目中
选项 1:
using App33;
using App33.iOS;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(AppShell), typeof(ShellCustomRenderer))]
namespace App33.iOS
{
public class ShellCustomRenderer : ShellRenderer
{
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new TabBarAppearance();
}
}
public class TabBarAppearance : IShellTabBarAppearanceTracker
{
public void Dispose()
{
}
public void ResetAppearance(UITabBarController controller)
{
}
public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
base.ViewWillAppear(animated);
UITabBar myTabBar = this.TabBarController.TabBar;
myTabBar.TintColor = UIColor.Red;
myTabBar.BarTintColor = UIColor.LightGray;
//... you can set style like above in iOS
AppShell.TabHeight = myTabBar.Bounds.Height;
}
public void UpdateLayout(UITabBarController controller)
{
}
}
}
选项 2:
实际上,UITabbar在iOS上的高度是一个固定值。在 iPhone 8 和之前是 49 并且 iPhone X 和之后(全屏)将有一个额外的 safeArea bottom height 。所以如果你只是想获取它(不需要设置高度),你可以直接使用DependencyService获取它,如下
AppShell.TabHeight = 49 + UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom;
在Android
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
// var hei=SupportActionBar.Height;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
int resourceId =Resources.GetIdentifier("design_bottom_navigation_height", "dimen", this.PackageName);
int height = 0;
if (resourceId > 0)
{
height = Resources.GetDimensionPixelSize(resourceId);
AppShell.TabHeight = height;
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
我在使用默认底部 TabBar
开发 Xamarin.Forms.Shell 应用程序,我需要知道 TabBar
height 调整一些项目。
我找到了在两个平台 StatusBar
高度 的方法,但我没有找到
可能吗?我只发现有关更改 Stack 上的 TabBar 高度的请求...
据我所知,在 Xamarin.Forms 中(还?)不可能检索到 TabBar
Height
,所以您可能需要根据 Platform 收集该信息。然后,利用 DependencyService
,您可以从 Xamarin.Forms 共享代码中获取该信息。那么,让我们来看看如何去做:
iOS
对于iOS,已经有像
Android
对于Android,您可以按如下方式检索TabBar高度
- 为依赖项 创建接口
注意:iOS部分也应该使用这个接口;)
namespace Tabbarheight
{
public interface IDisplayHeights
{
float GetTabBarHeight();
}
}
- 在 Android 中创建一个实现该接口的 class 和 returns 所需的值
(感谢@LucasZhang-MSFT 提供标识符字符串!)
using Android.App;
using Tabbarheight.Droid;
using Xamarin.Forms;
[assembly: Dependency(typeof(AndroidDisplayHeights))]
namespace Tabbarheight.Droid
{
class AndroidDisplayHeights : IDisplayHeights
{
public static Activity Activity { get; set; }
public float GetTabBarHeight()
{
int resourceId = Activity.Resources.GetIdentifier("design_bottom_navigation_height", "dimen", Activity.PackageName);
int height = 0;
if (resourceId > 0)
{
height = (int)(Activity.Resources.GetDimensionPixelSize(resourceId) / Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density);
}
return height;
}
}
}
其中Activity
由MainActivity.cs设置如下
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
AndroidDisplayHeights.Activity = this;
LoadApplication(new App());
}
- 最后,您可以按如下方式使用它
public AboutPage()
{
InitializeComponent();
SizeChanged += (s, a) =>
{
label.HeightRequest = DependencyService.Get<IDisplayHeights>().GetTabBarHeight();
label.BackgroundColor = Color.Red;
};
}
在上面的解决方案中,我定义了一个 Label
(标签)只是为了尝试通过设置 [=19= 来证明获得的 TabBar
的 Height
值的准确性]的身高。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Tabbarheight.Views.AboutPage"
xmlns:vm="clr-namespace:Tabbarheight.ViewModels"
Title="{Binding Title}">
<StackLayout>
<Label x:Name="label">
<Label.Text>
<x:String>
Hola mundo
</x:String>
</Label.Text>
</Label>
</StackLayout>
</ContentPage>
我这边的标签是这样的:
我们可以使用Custom Renderer
获取高度在 AppShell 中
public partial class AppShell : Xamarin.Forms.Shell
{
public static double TabHeight { get; set; }
//...
}
在iOS项目中
选项 1:
using App33;
using App33.iOS;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(AppShell), typeof(ShellCustomRenderer))]
namespace App33.iOS
{
public class ShellCustomRenderer : ShellRenderer
{
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new TabBarAppearance();
}
}
public class TabBarAppearance : IShellTabBarAppearanceTracker
{
public void Dispose()
{
}
public void ResetAppearance(UITabBarController controller)
{
}
public void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
base.ViewWillAppear(animated);
UITabBar myTabBar = this.TabBarController.TabBar;
myTabBar.TintColor = UIColor.Red;
myTabBar.BarTintColor = UIColor.LightGray;
//... you can set style like above in iOS
AppShell.TabHeight = myTabBar.Bounds.Height;
}
public void UpdateLayout(UITabBarController controller)
{
}
}
}
选项 2:
实际上,UITabbar在iOS上的高度是一个固定值。在 iPhone 8 和之前是 49 并且 iPhone X 和之后(全屏)将有一个额外的 safeArea bottom height 。所以如果你只是想获取它(不需要设置高度),你可以直接使用DependencyService获取它,如下
AppShell.TabHeight = 49 + UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom;
在Android
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
// var hei=SupportActionBar.Height;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
int resourceId =Resources.GetIdentifier("design_bottom_navigation_height", "dimen", this.PackageName);
int height = 0;
if (resourceId > 0)
{
height = Resources.GetDimensionPixelSize(resourceId);
AppShell.TabHeight = height;
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}