Xamarin Forms-Android标签栏,带有居中图标,无文本

时间:2018-07-19 20:57:26

标签: android xamarin.forms xamarin.android

我正在寻找从Xamarin Forms应用程序中TabbedPage上的选项卡中删除文本(并使图标垂直居中)的方法,

TabBar on iOS

我在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);
        }
    }
}

现在我在Android上的标签如下:

Android Tab Bar

如果有关系,可以将其设置在屏幕底部,如下所示:

public MyTabbedPage()
{
    On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
}

如何删除文本并使图标在Android标签栏上居中?我尝试过使用样式和axml,但是我什么都没得到。

谢谢!

4 个答案:

答案 0 :(得分:1)

可能有一些简单的方法可以从共享项目本身中完成。在这里使用customrenderer使其工作。 首先在Android项目的Layout文件夹中创建一个XML文件 custom_tab_layout.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="45dp"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="4dp"
        android:layout_marginBottom="4dp" />    
</LinearLayout>

根据您的喜好设置高度,边距和颜色。

现在在您的Android项目中添加.CS文件,说MyTabbedPageRenderer

[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(MyTabbedPageRenderer))]
namespace Myproject.Droid
{
    public class MyTabbedPageRenderer : TabbedPageRenderer
    {
        public MyTabbedPageRenderer(Context context) : base(context)
        {

        }
        protected override void SetTabIcon(TabLayout.Tab tab, FileImageSource icon)
        {
            base.SetTabIcon(tab, icon);
            tab.SetCustomView(Resource.Layout.custom_tab_layout);
            var imageview = tab.CustomView.FindViewById<ImageView>(Resource.Id.icon);
            imageview.SetBackgroundDrawable(tab.Icon);
        }
    }
}

代码ExportRenderer(typeof(MyTabbedPage)的第一行具有文件MyTabbedPage是您在问题中提到的共享项目类。在custom_tab_layout.axml文件中,您也可以添加TextView并可以在自定义渲染器中将文本指定为“”,以使图标的位置更好。 希望它能对您有所帮助。

答案 1 :(得分:1)

如果有人在寻找与@Alex West的代码相对应的iOS版本。

using RedSwipe.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer))]
namespace RedSwipe.iOS
{
    public class MyTabbedPageRenderer : TabbedRenderer
    {

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

            foreach (UITabBarItem item in this.TabBar.Items)
            {
                item.ImageInsets = new UIEdgeInsets(6, 0, -6, 0);
            }
        }
    }
}

答案 2 :(得分:0)

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

[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();
        }
    }
}

这可以达到所需的结果(无文本的居中图标)。尚未在不同尺寸的设备上进行测试,因此魔术数字9dp可能无法普遍使用。

答案 3 :(得分:0)

就像写了Alex West一样,但是对此进行了魔术填充

FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams)tab.GetChildAt(0).LayoutParameters;
lp.Height = LayoutParams.MatchParent;
lp.Gravity = GravityFlags.Center;

此外,您还可以选择修复GetAllChildView()这样的方法:

    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();
    }

并像这样GetAllChildViews<BottomNavigationMenuView>(ViewGroup)