如何在 Shell TabbedPage 应用程序、Xamarin 表单中更改图标和文本大小

Posted

技术标签:

【中文标题】如何在 Shell TabbedPage 应用程序、Xamarin 表单中更改图标和文本大小【英文标题】:How to change icon and text size in Shell TabbedPage app, Xamarin forms 【发布时间】:2021-03-13 00:04:34 【问题描述】:

我有一个带有 5 个选项卡的简单 shell 应用程序。我想根据应用屏幕大小更改图标和文本大小。

<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms" 
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:Ingly.Views"
       Title="App title"
       x:Class="MyApp.AppShell"
       Shell.NavBarIsVisible="False">

    <TabBar>
        <ShellContent Title="Store" Icon="icon_store.png" Route="AboutPage" ContentTemplate="DataTemplate local:AboutPage" />
        <ShellContent Title="Challenge" Icon="icon_challenge.png" ContentTemplate="DataTemplate local:ItemsPage" />
        <ShellContent Title="Learn"  Icon="icon_learn.png" ContentTemplate="DataTemplate local:ItemsPage" />
        <ShellContent Title="Words" Icon="icon_words.png" ContentTemplate="DataTemplate local:ItemsPage" />
        <ShellContent class="ss" Title="Profile" Icon="icon_profile.png" ContentTemplate="DataTemplate local:ItemsPage" />
    </TabBar>
</Shell>

我想根据应用屏幕大小更改图标和文本大小。从第二张截图可以看出,在较小的屏幕上几乎不可能阅读标签的标题。

【问题讨论】:

【参考方案1】:

来自Xamarin.Forms Shell Custom Renderers,通过shell自定义渲染更改标签栏文本大小和更改图标:

[assembly: ExportRenderer(typeof(AppShell), typeof(MyShellRenderer))]
namespace shellicon.Droid

public class MyShellRenderer : ShellRenderer

    public MyShellRenderer(Context context) : base(context)
    
    

    protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
    
        return new CustomBottomNavAppearance();
    


public class CustomBottomNavAppearance : IShellBottomNavViewAppearanceTracker

    public void Dispose()
    

    

   
    public void ResetAppearance(BottomNavigationView bottomView)
    
        throw new NotImplementedException();
    

   
    public void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
    
        var instance = MainActivity.mactivity;
        int width = instance.width;

        if(width>??)
        
            var bottomNavMenuView = bottomView.GetChildAt(0) as BottomNavigationMenuView;

            for (int i = 0; i < bottomNavMenuView.ChildCount; i++)
            
                var item = bottomNavMenuView.GetChildAt(i) as BottomNavigationItemView;
                var itemicon = item.GetChildAt(0);
                var itemTitle = item.GetChildAt(1);

                var IconImageView = (ImageView)itemicon;
                var smallTextView = ((TextView)((BaselineLayout)itemTitle).GetChildAt(0));
                var largeTextView = ((TextView)((BaselineLayout)itemTitle).GetChildAt(1));

                IconImageView.SetImageResource(Resource.Drawable.check);
                smallTextView.TextSize = 18;
                largeTextView.TextSize = 18;


            
        
       
    

在 Mainactivity.cs 中获取当前屏幕尺寸:

public class MainActivity : global::Xamarin.Forms.Platform.android.FormsAppCompatActivity

    public static MainActivity mactivity;
    public int width  get; set; 
    protected override void OnCreate(Bundle savedInstanceState)
    
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
       
        var metrics = Resources.DisplayMetrics;
        width = metrics.WidthPixels;
        mactivity = this;
    
    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    

【讨论】:

【参考方案2】:

安卓: 在 Android 上,您可以使用 LayerDrawable 设置 BottomNavigationView 的背景。在本例中,我根据选中的选项卡项计算了底线背景的位置和宽度,然后将其设置为 BottomNavigationView 背景。

public class ExtendedTabbedPageRenderer : TabbedPageRenderer
    
        Xamarin.Forms.TabbedPage tabbedPage;
        BottomNavigationView bottomNavigationView;
        private bool firstTime = true;

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

            if (e.NewElement != null)
            
                tabbedPage = e.NewElement as ExtendedTabbedPage;
                bottomNavigationView = (GetChildAt(0) as Android.Widget.RelativeLayout).GetChildAt(1) as BottomNavigationView;
                bottomNavigationView.NavigationItemSelected += BottomNavigationView_NavigationItemSelected;
            

        
       
        protected override void OnLayout(bool changed, int l, int t, int r, int b)
        
            base.OnLayout(changed, l, t, r, b);
           
            if (firstTime && bottomNavigationView != null)
            
                for (int i = 0; i < Element.Children.Count; i++)
                
                    var item = bottomNavigationView.Menu.GetItem(i);
                    if (bottomNavigationView.SelectedItemId == item.ItemId)
                    
                        SetupBottomNavigationView(item);
                        break;
                    
                
                firstTime = false;
            
        

        void BottomNavigationView_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e)
        
            SetupBottomNavigationView(e.Item);
            this.OnNavigationItemSelected(e.Item);
        

        //Adding line view
        void SetupBottomNavigationView(IMenuItem item)
        
            int lineBottomOffset = 8;
            int lineWidth = 4;
            int itemHeight = bottomNavigationView.Height - lineBottomOffset;
            int itemWidth = (bottomNavigationView.Width / Element.Children.Count);
            int leftOffset = item.ItemId * itemWidth;
            int rightOffset = itemWidth * (Element.Children.Count - (item.ItemId + 1));
            GradientDrawable bottomLine = new GradientDrawable();
            bottomLine.SetShape(ShapeType.Line);
            bottomLine.SetStroke(lineWidth, Xamarin.Forms.Color.DarkGray.ToAndroid());

            var layerDrawable = new LayerDrawable(new Drawable[]  bottomLine );
            layerDrawable.SetLayerInset(0, leftOffset, itemHeight, rightOffset, 0);

            bottomNavigationView.SetBackground(layerDrawable);
         

更多详情请点击此链接 https://xamgirl.com/extending-tabbedpage-in-xamarin-forms/

【讨论】:

【参考方案3】:

如果您的 Android 项目的 Resources/values 文件夹不存在,请创建一个新文件 dimens.xml。然后添加以下 XML 以覆盖文本处于活动状态和非活动状态时的大小:

<resources xmlns:tools="http://schemas.android.com/tools">
    <dimen name="design_bottom_navigation_text_size" tools:override="true">12sp</dimen>
    <dimen name="design_bottom_navigation_active_text_size" tools:override="true">12sp</dimen>
</resources>

您必须使用 Android API 版本 28 或更高版本。

更多信息可以在这里找到:https://montemagno.com/control-text-size-on-android-bottom-navigation/

【讨论】:

以上是关于如何在 Shell TabbedPage 应用程序、Xamarin 表单中更改图标和文本大小的主要内容,如果未能解决你的问题,请参考以下文章

TabbedPage 导航和 Shell 选项卡导航有啥区别

如何在 Xamarin.Forms 的 TabbedPage 的选项卡中放置一个按钮?

TabbedPage 内的 xamarin mvvmcross TabbedPage

使用条件时如何从 TabbedPage 隐藏选项卡(xamarin 表单)

如何在 Xamarin.Forms-Android 的 TabbedPage-BottomNavigation Bar 中删除 BarItemColor 和 SelectedBarItemColor?

如何将 TabbedPage ContentPage 拆分为不同的文件