Anton Tropashko
Anton Tropashko

Reputation: 5806

How do I detect tab was touched in xamarin forms TabbedPage

How could I detect tab was touched in xamarin forms TabbedPage? (which is different from page changed detection which I figured how to detect)

Here is why: I'm trying to work around a rather ugly tabbed page overflow UI (the ugly scroller that shows up on the right over the tabbar whenever there are >5 tabs) So the 5th tab press shows a custom menu, second press hides that menu, etc.

Thanks!

Upvotes: 13

Views: 12764

Answers (2)

fmaccaroni
fmaccaroni

Reputation: 3916

It has been a while since this was asked but just in case here is an answer.

Perform an action when a tab is tapped is the same as when:

  • The tab has changed
  • The tab is "reselected"

So for the first one you can use @femil-shajin 's answer or as I do here which is more direct and for the second one you need to make some custom renderers for the TabbedPage:

public class MyTabbedPage : TabbedPage
{
    ...

    protected override void OnCurrentPageChanged()
    {
         // do whatever
    }    
    
    public void OnTabReselected()
    {
         // do whatever
    }

    ...
}

Then on Android:

[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
namespace MyNamespace.Droid.Renderers
{
    public class CustomTabbedRenderer : TabbedPageRenderer, NavigationBarView.IOnItemReselectedListener
    {
        ...
        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                GetBottomNavigationView()?.SetOnItemReselectedListener(this);
            }
        }

        private BottomNavigationView GetBottomNavigationView()
        {
            // this may need to change on some cases 
            for (var i = 0; i < ViewGroup.ChildCount; i++)
            {
                var childView = ViewGroup.GetChildAt(i);
                if (childView is ViewGroup viewGroup)
                {
                    for (var j = 0; j < viewGroup.ChildCount; j++)
                    {
                        var childRelativeLayoutView = viewGroup.GetChildAt(j);
                        if (childRelativeLayoutView is BottomNavigationView bottomNavigationView)
                        {
                            return bottomNavigationView;
                        }
                    }
                }
            }
            return null;
        }

        public void OnNavigationItemReselected(IMenuItem item)
        {
            if (Element is MyTabbedPage tabbedPage)
            {
                tabbedPage.OnTabReselected();
            }
        } 
        ...
    }
}

And on iOS:

[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
namespace MyNamespace.iOS.Renderers
{
    public class CustomTabbedRenderer : TabbedRenderer
    {
        private UITabBarItem _previousSelectedItem;

        ...
        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);

            if (SelectedIndex < TabBar.Items.Length)
            {
                _previousSelectedItem = TabBar.Items[SelectedIndex];
            }
        }

        public override void ItemSelected(UITabBar tabbar, UITabBarItem item)
        {
            if (_previousSelectedItem == item && Element is MyTabbedPage tabbedPage)
            {
                tabbedPage.OnTabReselected();
            }
            _previousSelectedItem = item;
        }
        ...
    }
}

Source: Part of this was based on this page

Upvotes: 2

Femil Shajin
Femil Shajin

Reputation: 1808

If you are trying to find which page is selected in TabbedPage you could do it in this way. With Index value you can perform whatever action you want..

Event for detecting page no:

    this.CurrentPageChanged += (object sender, EventArgs e) => {
            var i = this.Children.IndexOf(this.CurrentPage);
            System.Diagnostics.Debug.WriteLine("Page No:"+i);
        };

Upvotes: 29

Related Questions