Xamarin表单 - 带有居中图标且没有文本的Android标签栏

问题描述 投票:0回答:3

我想在我的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图标栏上的图标居中?我已经尝试过使用款式和轴,但我根本没有得到任何东西。

谢谢!

android xamarin.forms xamarin.android
3个回答
1
投票

共享项目本身可能有一些简单的方法。这里使用customrenderer使其工作。首先在Android项目custom_tab_layout.axml中的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并在自定义渲染器中将文本设置为“”,以便为您的图标提供更好的位置。希望它对你有所帮助。


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可能无法普遍使用。


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)

© www.soinside.com 2019 - 2024. All rights reserved.