Я работаю над приложением Xamarin.Forms.Shell, используя нижнюю часть TabBar по умолчанию, и мне нужно знать TabBar высоту, чтобы настроить некоторые элементы.
Я нашел способ получить StatusBar height на обеих платформах там, но я не нашел решения для TabBar.
Является ли это возможным? Я нашел только запросы об изменении высоты TabBar в стеке...
Ответ 1 · рейтинг 4 · Lucas Zhang
Мы могли бы получить высоту с помощью 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. Поэтому, если вы просто хотите получить его (не нужно устанавливать высоту), вы можете получить его напрямую, используя 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);
}
}
}
Ответ 2 · рейтинг 2 · Deczaloth
Насколько мне известно, в Xamarin.Forms невозможно (пока?) получить TabBar Height, поэтому вам, возможно, придется собирать эту информацию для каждой платформы. . Затем, используя DependencyService, вы сможете сделать эту информацию доступной из общего кода Xamarin.Forms. Итак, давайте посмотрим, как это сделать:
iOS
Для iOS уже были опубликованы ответы, такие как это, чтобы объяснить, как это можно сделать.
Андроид
Для Android вы можете получить высоту TabBar следующим образом.
- Создайте Интерфейс для зависимости
Примечание. Этот интерфейс также следует использовать в части iOS;)
namespace Tabbarheight
{
public interface IDisplayHeights
{
float GetTabBarHeight();
}
}
- Создайте в Android класс, который реализует этот интерфейс и возвращает нужное значение.
(спасибо @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 (метку) просто для того, чтобы попытаться продемонстрировать точность полученного значения Height TabBar, установив высоту Label.
<?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>
На моей стороне этикетка выглядит так: