androidmauihandlertabbarbottomtabs

.Net Maui: How to access Bottom Tabbar as type BottomNavigationView using TabbedViewHandler on android platform?


I am working on a .Net Maui app where I have to retrieve bottom tabs on android. I am using TabbedViewHandler to achieve this. The problem is there is no child in the ViewGroup of TabbedViewHandler having type BottomNavigationView. Instead I get a child of type RecyclerView in the ViewGroup.

Can someone help me in accessing bottom tabs? Thanks in advance.

  1. CustomTabbedViewHandler
using Android.Content;
using Android.Views;
using Google.Android.Material.BottomNavigation;
using Microsoft.Maui.Controls.Handlers;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Controls.Platform;
using AndroidX.AppCompat.Widget;

namespace SampleApp1
{
    public class CustomTabbedViewHandler : TabbedViewHandler
    {
        public CustomTabbedViewHandler(Context context) : base(context)
        {
        }

        protected override void ConnectHandler(View nativeView)
        {
            base.ConnectHandler(nativeView);

            // Access the ViewGroup containing the tabs
            var viewGroup = nativeView as ViewGroup;

            if (viewGroup != null)
            {
                // Retrieve the BottomNavigationView
                var bottomNavigationView = GetBottomNavigationView(viewGroup);

                if (bottomNavigationView != null)
                {
                    // Perform operations on the BottomNavigationView here
                }
            }
        }

        private BottomNavigationView GetBottomNavigationView(ViewGroup viewGroup)
        {
            for (int i = 0; i < viewGroup.ChildCount; i++)
            {
                var child = viewGroup.GetChildAt(i);

                if (child is BottomNavigationView bottomNavigationView)
                {
                    return bottomNavigationView;
                }
                else if (child is ViewGroup childViewGroup)
                {
                    var result = GetBottomNavigationView(childViewGroup);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }
    }
}

  1. CustomTabbedView.cs
public class CustomTabbedView : TabbedPage
{

}
  1. CustomTabbedPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<controls:CustomTabbedView
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:SampleApp1"
    xmlns:android="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;assembly=Microsoft.Maui.Controls"
    android:TabbedPage.ToolbarPlacement="Bottom"
    android:TabbedPage.IsSwipePagingEnabled="False"
    x:Class="SampleApp1.CustomTabbedPage">
</controls:CustomTabbedView>
  1. CustomTabbedPage.xaml.cs
namespace SampleApp1;

public partial class CustomTabbedPage : CustomTabbedView
{
    public CustomTabbedPage()
    {
        InitializeComponent();

        AddViews();

        Title = CurrentPage.Title;
        base.OnCurrentPageChanged();
    }

    protected override void OnCurrentPageChanged()
    {
        base.OnCurrentPageChanged();
        Title = CurrentPage.Title;
    }

    private void AddViews()
    {
        var home = new HomePage() { Title = "Home" };
        this.Children.Add(home);

        var detailView = new DetailPage() { Title = "Details" };
        this.Children.Add(detailView);
    }
}

HomePage and DetailPage are simple content pages here added from code behind. I confirm that I registered the handlers in MauiProgram.cs file.


Solution

  • Can you please explain a bit more about ShellBottomNavViewAppearanceTracker? Fyi, there is only TabbedPage used in the app.

    If you are developing a Shell app, you can get BottomNavigationView by ShellRenderer and ShellBottomNavViewAppearanceTracker.

    namespace MauiApp2.Platforms.Android
    {
        public partial class ShellHandlerEx : ShellRenderer
        {
            protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
            {
                return new ShellBottomNavViewAppearanceTrackerEx(this, shellItem.CurrentItem);
            }
        }
    }
    
    namespace MauiApp2.Platforms.Android
    {
        class ShellBottomNavViewAppearanceTrackerEx : ShellBottomNavViewAppearanceTracker
        {
            private readonly IShellContext shellContext;
    
            public ShellBottomNavViewAppearanceTrackerEx(IShellContext shellContext, ShellItem shellItem) : base(shellContext, shellItem)
            {
                this.shellContext = shellContext;
            }
    
            public override void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
            {
    
                base.SetAppearance(bottomView, appearance);
                ....
            }
        }
    }
    
    var builder = MauiApp.CreateBuilder();
    builder.UseMauiApp<App>()
        ....
        .ConfigureMauiHandlers(handlers =>
        {
             handlers.AddHandler<Shell, ShellHandlerEx>();
        });
    

    If you are developing a TabbedPage app, you can refer to this discussion on MAUI GitHub: How to access BottomNavigationView from TabbedView handler? #16344. It gets BottomNavigationView by using reflection.