Xamarin.Forms.Shell : 아래쪽 TabBar 높이를 가져 오는 방법은 무엇입니까?

Nov 18 2020

기본 bottom을 사용하여 Xamarin.Forms.Shell 앱 에서 작업하며 일부 항목을 조정 TabBar하려면 TabBar 높이 를 알아야합니다 .

내가 얻을 수있는 방법을 발견했습니다 StatusBar 높이 두 플랫폼 모두에서 존재를 ,하지만 난에 대한 해결책을 발견하지 않았다 TabBar.

가능합니까? Stack의 TabBar 높이 변경에 대한 요청 만 찾았습니다.

답변

3 LucasZhang-MSFT Nov 18 2020 at 20:15

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 :

실제로 iOS 에서 UITabbar 의 높이는 고정 된 값입니다. 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);
        }
    }
}
1 Deczaloth Nov 18 2020 at 20:14

내가 아는 한, Xamarin.Forms에서는를 검색하는 것이 (아직?) 불가능 TabBar Height하므로 Platform 별로 해당 정보를 수집해야 할 수 있습니다 . 그런 다음 DependencyService사용자를 활용하면 Xamarin.Forms 공유 코드 에서 해당 정보를 사용할 수 있습니다 . 그래서 어떻게하는지 살펴 보자 :

iOS

들어 아이폰 OS , 이미 같은 답변이 게시 된 이 어떻게이 작업을 수행 할 수 있습니다 설명.

기계적 인조 인간

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;

        }
    }
}

MainActivity.cs 에서 다음과 같이 Activity설정되는 위치

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(라벨)을 간단히 받고 정확도 증명하려고 TabBarHeight설정에 따라 값 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>

라벨은 내 옆에 다음과 같이 보입니다.