简体   繁体   中英

How to change icon and text size in Shell TabbedPage app, Xamarin forms

I have a simple shell app with 5 tabs. I would like to change icon and text sizes based on app screen size.

<?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>

在此处输入图像描述

I would like to change icon and text sizes based on app screen size. As you can see from the second screenshot, it is almost impossible to read the title of the tab on a smaller screen.

在此处输入图像描述

Android: On Android, you can use a LayerDrawable to set the background on the BottomNavigationView. In this case, I calculated the position and width for the bottom line background based on the tab item that's selected, then set it as the BottomNavigationView background.

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

For more details follow this link https://xamgirl.com/extending-tabbedpage-in-xamarin-forms/

From Xamarin.Forms Shell Custom Renderers , change tab bar text size and change icon by shell custom render:

[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;


            }
        }
       
    }
}

Getting current screen size in 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);
    }
}

Inside of your Android project's Resources/values folder create a new file dimens.xml if it doesn't exist. Then add the following XML to override the size of the text when it is active and not active:

<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>

You must be using Android API version 28 and higher.

More information can be found here: https://montemagno.com/control-text-size-on-android-bottom-navigation/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM