我正在寻找从Xamarin Forms应用程序中TabbedPage上的选项卡中删除文本(并使图标垂直居中)的方法,
我在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上的标签如下:
如果有关系,可以将其设置在屏幕底部,如下所示:
public MyTabbedPage()
{
On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
}
如何删除文本并使图标在Android标签栏上居中?我尝试过使用样式和axml,但是我什么都没得到。
谢谢!
答案 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)