Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Xamarin.Forms.Shell: как получить высоту нижней панели вкладок?

Автор вопроса: Gold.strikeОтветов: 2

Я работаю над приложением Xamarin.Forms.Shell, используя нижнюю часть TabBar по умолчанию, и мне нужно знать TabBar высоту, чтобы настроить некоторые элементы.

Я нашел способ получить StatusBar height на обеих платформах там, но я не нашел решения для TabBar.

Является ли это возможным? Я нашел только запросы об изменении высоты TabBar в стеке...

  • Это работает сейчас? Lucas Zhang 20.11.2020

iosandroidtabbarheight

Ответы

Ответ 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>

На моей стороне этикетка выглядит так:

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы