Xamarin表单-带居中图标的Android选项卡栏&;没有文本

Xamarin表单-带居中图标的Android选项卡栏&;没有文本,android,xamarin.forms,xamarin.android,Android,Xamarin.forms,Xamarin.android,我希望在我的Xamarin Forms应用程序中删除选项卡页面上的文本(并将图标垂直居中),如下所示: 我在iOS上通过使TextColor清晰并在自定义渲染器中向下移动图像实现了这一点: public override void ViewWillLayoutSubviews() { base.ViewWillLayoutSubviews(); if (TabBar != null) { foreach (var item in TabBar.Item

我希望在我的Xamarin Forms应用程序中删除选项卡页面上的文本(并将图标垂直居中),如下所示:

我在iOS上通过使TextColor清晰并在自定义渲染器中向下移动图像实现了这一点:

public override void ViewWillLayoutSubviews()
{
    base.ViewWillLayoutSubviews();

    if (TabBar != null)
    {
        foreach (var item in TabBar.Items)
        {
            item.ImageInsets = new UIEdgeInsets(5, 0, -5, 0);
        }
    }
}
[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer ))]
namespace MyApp.Droid.Renderers
{
    public class MyTabbedPageRenderer : TabbedPageRenderer
    {
        public MyTabbedPageRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);

            var childViews = GetAllChildViews(ViewGroup);

            var scale = Resources.DisplayMetrics.Density;
            var paddingDp = 9;
            var dpAsPixels = (int)(paddingDp * scale + 0.5f);

            foreach (var childView in childViews)
            {                
                if (childView is BottomNavigationItemView tab)
                {                    
                    tab.SetPadding(tab.PaddingLeft, dpAsPixels, tab.PaddingRight, tab.PaddingBottom);
                }
                else if (childView is TextView textView)
                {                 
                    textView.SetTextColor(Android.Graphics.Color.Transparent);
                }
            }
        }

        List<Android.Views.View> GetAllChildViews(Android.Views.View view)
        {
            if (!(view is ViewGroup group))
            {
                return new List<Android.Views.View> { view };
            }

            var result = new List<Android.Views.View>();

            for (int i = 0; i < group.ChildCount; i++)
            {
                var child = group.GetChildAt(i);

                var childList = new List<Android.Views.View> { child };
                childList.AddRange(GetAllChildViews(child));

                result.AddRange(childList);
            }

            return result.Distinct().ToList();
        }
    }
}
现在,我在Android上的标签如下所示:

如果重要的话,它被设置在屏幕底部,如下所示:

public MyTabbedPage()
{
    On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
}
publicMyTabbedPage()
{
On().SetToolbarPlacement(ToolbarPlacement.Bottom);
}
如何在Android选项卡栏上删除文本并将图标居中?我尝试过使用styles和axml,但一无所获


谢谢

也许有一些简单的方法可以从共享项目本身做到这一点。这里使用customrenderer使其工作。 首先在Android项目的布局文件夹中创建xaml文件 自定义_选项卡_layout.xaml

代码
ExportRenderer(typeof(MyTabbedPage)
have file
MyTabbedPage
的第一行是您在问题中提到的共享项目类。在custom_tab_layout.xaml文件中,您也可以添加TextView,并可以在custom renderer中将文本设置为“”,以便为图标提供更好的位置。
希望它能对您有所帮助。

也许有一些简单的方法可以从共享项目本身实现这一点。这里使用customrenderer让它工作起来。 首先在Android项目的布局文件夹中创建xaml文件 自定义_选项卡_layout.xaml

代码
ExportRenderer(typeof(MyTabbedPage)
have file
MyTabbedPage
的第一行是您在问题中提到的共享项目类。在custom_tab_layout.xaml文件中,您也可以添加TextView,并可以在custom renderer中将文本设置为“”,以便为图标提供更好的位置。
希望它能对您有所帮助。

最后,我拼凑了一个类似于iOS的解决方案,使用以下渲染器:

public override void ViewWillLayoutSubviews()
{
    base.ViewWillLayoutSubviews();

    if (TabBar != null)
    {
        foreach (var item in TabBar.Items)
        {
            item.ImageInsets = new UIEdgeInsets(5, 0, -5, 0);
        }
    }
}
[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer ))]
namespace MyApp.Droid.Renderers
{
    public class MyTabbedPageRenderer : TabbedPageRenderer
    {
        public MyTabbedPageRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);

            var childViews = GetAllChildViews(ViewGroup);

            var scale = Resources.DisplayMetrics.Density;
            var paddingDp = 9;
            var dpAsPixels = (int)(paddingDp * scale + 0.5f);

            foreach (var childView in childViews)
            {                
                if (childView is BottomNavigationItemView tab)
                {                    
                    tab.SetPadding(tab.PaddingLeft, dpAsPixels, tab.PaddingRight, tab.PaddingBottom);
                }
                else if (childView is TextView textView)
                {                 
                    textView.SetTextColor(Android.Graphics.Color.Transparent);
                }
            }
        }

        List<Android.Views.View> GetAllChildViews(Android.Views.View view)
        {
            if (!(view is ViewGroup group))
            {
                return new List<Android.Views.View> { view };
            }

            var result = new List<Android.Views.View>();

            for (int i = 0; i < group.ChildCount; i++)
            {
                var child = group.GetChildAt(i);

                var childList = new List<Android.Views.View> { child };
                childList.AddRange(GetAllChildViews(child));

                result.AddRange(childList);
            }

            return result.Distinct().ToList();
        }
    }
}
[程序集:ExportRenderer(typeof(TabbedPage)、typeof(MyTabbedPageRenderer))]
命名空间MyApp.Droid.Renderers
{
公共类MyTabbedPageRenderer:TabbedPageRenderer
{
公共MyTabbedPageRenderer(上下文):基本(上下文)
{
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
var childview=getAllChildView(视图组);
var scale=Resources.DisplayMetrics.Density;
var paddingDp=9;
变量dpAsPixels=(int)(填充dp*比例+0.5f);
foreach(childView中的var childView)
{                
如果(子视图为底部导航项视图选项卡)
{                    
tab.SetPadding(tab.PaddingLeft,dpAsPixels,tab.PaddingRight,tab.PaddingBottom);
}
else if(儿童视图为文本视图文本视图)
{                 
SetTextColor(Android.Graphics.Color.Transparent);
}
}
}
列出GetAllChildView(Android.Views.View)
{
如果(!(视图为视图组))
{
返回新列表{view};
}
var result=新列表();
对于(int i=0;i

这达到了预期的效果(居中的图标没有文本)。还没有在不同大小的设备上测试它,因此magic number 9dp可能无法普遍工作。

最后,我拼凑了一个类似于iOS的解决方案,使用此渲染器:

public override void ViewWillLayoutSubviews()
{
    base.ViewWillLayoutSubviews();

    if (TabBar != null)
    {
        foreach (var item in TabBar.Items)
        {
            item.ImageInsets = new UIEdgeInsets(5, 0, -5, 0);
        }
    }
}
[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer ))]
namespace MyApp.Droid.Renderers
{
    public class MyTabbedPageRenderer : TabbedPageRenderer
    {
        public MyTabbedPageRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);

            var childViews = GetAllChildViews(ViewGroup);

            var scale = Resources.DisplayMetrics.Density;
            var paddingDp = 9;
            var dpAsPixels = (int)(paddingDp * scale + 0.5f);

            foreach (var childView in childViews)
            {                
                if (childView is BottomNavigationItemView tab)
                {                    
                    tab.SetPadding(tab.PaddingLeft, dpAsPixels, tab.PaddingRight, tab.PaddingBottom);
                }
                else if (childView is TextView textView)
                {                 
                    textView.SetTextColor(Android.Graphics.Color.Transparent);
                }
            }
        }

        List<Android.Views.View> GetAllChildViews(Android.Views.View view)
        {
            if (!(view is ViewGroup group))
            {
                return new List<Android.Views.View> { view };
            }

            var result = new List<Android.Views.View>();

            for (int i = 0; i < group.ChildCount; i++)
            {
                var child = group.GetChildAt(i);

                var childList = new List<Android.Views.View> { child };
                childList.AddRange(GetAllChildViews(child));

                result.AddRange(childList);
            }

            return result.Distinct().ToList();
        }
    }
}
[程序集:ExportRenderer(typeof(TabbedPage)、typeof(MyTabbedPageRenderer))]
命名空间MyApp.Droid.Renderers
{
公共类MyTabbedPageRenderer:TabbedPageRenderer
{
公共MyTabbedPageRenderer(上下文):基本(上下文)
{
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
var childview=getAllChildView(视图组);
var scale=Resources.DisplayMetrics.Density;
var paddingDp=9;
变量dpAsPixels=(int)(填充dp*比例+0.5f);
foreach(childView中的var childView)
{                
如果(子视图为底部导航项视图选项卡)
{                    
tab.SetPadding(tab.PaddingLeft,dpAsPixels,tab.PaddingRight,tab.PaddingBottom);
}
else if(儿童视图为文本视图文本视图)
{                 
SetTextColor(Android.Graphics.Color.Transparent);
}
}
}
列出GetAllChildView(Android.Views.View)
{
如果(!(视图为视图组))
{
返回新列表{view};
}
var result=新列表();
对于(int i=0;i
这达到了预期的效果(图标居中,没有文本)。尚未在不同大小的设备上进行测试,因此magic number 9dp可能无法普遍工作。

如所述,但修复了此项的magic padding

FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams)tab.GetChildAt(0).LayoutParameters;
lp.Height = LayoutParams.MatchParent;
lp.Gravity = GravityFlags.Center;
另外,您还可以选择修复如下方法:

    List<T> GetAllChildViews<T>(Android.Views.View view) where T: Android.Views.View
    {
        if (!(view is ViewGroup group))
        {
            if(view is T)
            {
                return new List<T> { view as T };
            }

            return new List<T>();
        }

        var result = new List<T>();

        for (int i = 0; i < group.ChildCount; i++)
        {
            var child = group.GetChildAt(i);

            var childList = new List<T>();
            if(child is T item)
            {
                childList.Add(item);
            }
            else
            {
                childList.AddRange(GetAllChildViews<T>(child));
            }

            result.AddRange(childList);
        }

        return result.Distinct().ToList();
    }
列出GetAllChildView(Android.Views.View),其中T:Android.Views.View
{
如果(!(视图为视图组))
{