【问题标题】:How can I customize the appearance of top tabs (ShellSection) in Xamarin Shell?如何在 Xamarin Shell 中自定义顶部选项卡 (ShellSection) 的外观?
【发布时间】:2021-03-20 00:17:12
【问题描述】:

我做了很多研究:

但是,我找不到如何正确实现我的想法。

我的应用程序使用带有弹出菜单的 Xamarin Shell,并且某些页面显示了顶部选项卡栏。举个例子,我的应用是这样的:

Xamarin Shell provides a simple way to create these multi-tabs pages。现在,我想自定义这些选项卡并更改字体、选择指示器的颜色等。一开始,我以为我可以在我的Android项目的styles.xml文件中创建一个特定的样式,然后在android.support.design.widget.TabLayout中引用它。举个例子,我在 Xamarin 解决方案的 Android 项目中的 Tabbar.xml 文件中做了这样的事情:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:id="@+id/sliding_tabs"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="?attr/colorPrimary"
   android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
   app:tabIndicatorColor="@android:color/white"
   style="@style/MyCustomTabLayout"
   app:tabGravity="fill"
   app:tabMode="fixed" />

并且这个在styles.xml文件中总是在解决方案的Android项目中:

<?xml version="1.0" encoding="utf-8" ?>
<resources>
  <style name="MainTheme" parent="MainTheme.Base">
    <item name="android:textAllCaps">false</item>
  </style>

  <style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
    <item name="tabIndicatorColor">#FFFFFF</item>
    <item name="tabIndicatorHeight">3dp</item>
    <item name="tabSelectedTextColor">#FFFFFF</item>
  </style>
</resources>

但是,什么也没发生,样式也没有应用。我认为这是对如何真正实现我的想法的误解,并且我认为“子”顶部标签栏可能不被认为是真正的TabLayout,因为它只是ShellSection 的产物。最后,我发现也许我需要的是custom renderer。我正在实现它,但我被困在这个问题上:我不明白如何设置ShellSection 的外观。我当前的自定义渲染器代码是这样的:

[assembly: ExportRenderer(typeof(AppShell), typeof(CustomShellRenderer))]
namespace A {
    internal class CustomShellRenderer : ShellRenderer {
        public CustomShellRenderer(Context context) : base(context) { }

        protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection) {
            return new CustomShellSectionAppearance(this);
        }
    }

    class CustomShellSectionAppearance : ShellSectionRenderer {
        public Fragment Fragment { get; }
        public event EventHandler AnimationFinished;
        public void Dispose() {
            throw new NotImplementedException();
        }

        public ShellSection ShellSection { get; set; }

        public CustomShellSectionAppearance(IShellContext shellContext) : base(shellContext) { }

        // I thought I need to make my customization here, but it was only a guess:
        // I found nobody talking about customizing a ShellSection on the Web
        protected override void SetAppearance(ShellAppearance appearance) {
            base.SetAppearance(appearance);
            appearance.TabBarDisabledColor = Color.Aqua; // ERROR: appearance has only "get" properties
        }
    }
}

我在自定义 Xamarin 应用程序顶部选项卡栏的外观的过程中是否遗漏了什么?

【问题讨论】:

    标签: c# android xamarin.forms custom-renderer xamarin.forms.shell


    【解决方案1】:

    您可以使用以下 Shell 自定义渲染器来实现。

    • 对于颜色:SetColors(TabLayout tabLayout, Color foreground, Color background, Color title, Color unselected) 方法的参数名称一目了然。
    • 如果在下面的代码中 Color 类型前面没有命名空间,那么它来自 XF,因为 using Color = Xamarin.Forms.Color;
    • 对于字体,您需要创建自定义视图并定义所需的任何属性。
    • 当使用TabSelectedTabUnSelected 事件更改选择时,您可以修改属性、更改样式或执行任何逻辑,在我的演示中,我在文本上应用粗体并在选择选项卡时使其变大,并在选项卡时恢复未选中,您也可以在那里实现漂亮的动画。
    public class MyShellRenderer : ShellRenderer
    {
        public MyShellRenderer(Context context) : base(context)
        {
        }
    
        protected override IShellTabLayoutAppearanceTracker CreateTabLayoutAppearanceTracker(ShellSection shellSection)
            => new MyTabLayoutAppearanceTracker(this);
    }
    
    
    public class MyTabLayoutAppearanceTracker : ShellTabLayoutAppearanceTracker
    {
        public MyTabLayoutAppearanceTracker(IShellContext shellContext) : base(shellContext)
        {
        }
    
        public override void SetAppearance(TabLayout tabLayout, ShellAppearance appearance)
        {
            base.SetAppearance(tabLayout, appearance);
            tabLayout.TabSelected += TabLayout_TabSelected;
            tabLayout.TabUnselected += TabLayout_TabUnselected;
    
            for (var i = 0; i < tabLayout.TabCount; i++)
            {
                TabLayout.Tab tab = tabLayout.GetTabAt(i);
                if (tab.CustomView == null)
                {
                    TextView textview = new TextView(Android.App.Application.Context)
                    {
                        Text = tabLayout.GetTabAt(i).Text,
                        TextSize = 20,
                        Typeface = Typeface.DefaultBold
                    };
                    textview.SetTextColor(Android.Graphics.Color.Black);
                    tab.SetCustomView(textview);
                }
            }
            base.SetColors(tabLayout, Color.Red, Color.Yellow, Color.Black, Color.Gray);
        }
            private void TabLayout_TabUnselected(object sender, TabLayout.TabUnselectedEventArgs e)
            {
                if (e.Tab?.CustomView is TextView textView)
                {
                    textView.Typeface = Typeface.Default;
                    textView.TextSize = 15;
                }
            }
    
            private void TabLayout_TabSelected(object sender, TabLayout.TabSelectedEventArgs e)
            {
                if (e.Tab?.CustomView is TextView textView)
                {
                    textView.Typeface = Typeface.DefaultBold;
                    textView.TextSize = 20;
                }
            }
    }
    


    编辑

    没有自定义渲染器的更简单的解决方案?

    看看TabView 来自xamarin-communitytoolkit 包。

    【讨论】:

    • 这可能也会影响底部的 Tabs 对吧?
    【解决方案2】:

    如果您想更改选定选项卡的颜色而无需使用自定义渲染器,您可以通过编辑 Shell 选项卡的 ShellUnselectedColor、ShellTitleColor 和 ShellForegroundColor 来实现:

      <Style x:Key="BaseStyle"
                       TargetType="Element">
                    <Setter Property="Shell.BackgroundColor"
                            Value="{StaticResource Primary}" />
                    <Setter Property="Shell.ForegroundColor"
                            Value="White" />
                    <Setter Property="Shell.TitleColor"
                            Value="White" />
                    <Setter Property="Shell.DisabledColor"
                            Value="#B4FFFFFF" />
                    <Setter Property="Shell.UnselectedColor"
                            Value="#95FFFFFF" />
                    <Setter Property="Shell.TabBarBackgroundColor"
                            Value="{StaticResource Primary}" />
                    <Setter Property="Shell.TabBarForegroundColor"
                            Value="White" />
                    <Setter Property="Shell.TabBarUnselectedColor"
                            Value="#95FFFFFF" />
                    <Setter Property="Shell.TabBarTitleColor"
                            Value="White" />
                </Style>
    

    【讨论】:

    • 我相信这也会影响底部标签和导航栏。 @op 也想改变字体。
    猜你喜欢
    • 2011-12-13
    • 1970-01-01
    • 2017-01-05
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多