Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Forms TabbedPage event when current tab is tapped to refresh the page

I'm using Xamarin.Forms to build an iOS/Android app, and have a TabbedPage.

If a user is already on Tab 2, and Tab2 is clicked, and I want either the tab2 to refresh, or for a function of my own to run so I can refresh it myself.

Is there a way to do this within Xamarin.Forms or a way to do it with custom renderers?

like image 399
Kyle Avatar asked Mar 15 '17 04:03

Kyle


2 Answers

Here is how I ended up solving the issue. My TabbedPage consisted of a NavigationPage for each tab, so if you are not using navigation pages your code will have to change a little bit but only slightly. You can put your "refresh" logic inside of OnTabbarControllerItemSelected for iOS and OnTabbarControllerItemSelected for Android. Check out the code below.

Android Renderer (courtesy of Mike Ma)

using Android.Support.Design.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
[assembly: ExportRenderer(typeof(MainTabbedPage), typeof(MainPageRenderer))]
namespace YourNameSpace
{
    public class MainPageRenderer : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
    {
        private MainTabbedPage _page;
        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                _page = (MainTabbedPage)e.NewElement;
            }
            else
            {
                _page = (MainTabbedPage)e.OldElement;
            }

        }
        async void TabLayout.IOnTabSelectedListener.OnTabReselected(TabLayout.Tab tab)
        {
            await _page.CurrentPage.Navigation.PopToRootAsync();
        }
    }
}

iOs Renderer:

using UIKit;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(MainTabbedPage), typeof(MainPageRenderer))]
namespace YourNameSpace
{
    public class MainPageRenderer : TabbedRenderer
    {
        private MainTabbedPage _page;
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                _page = (MainTabbedPage)e.NewElement;
            }
            else
            {
                _page = (MainTabbedPage)e.OldElement;
            }

            try
            {
                var tabbarController = (UITabBarController)this.ViewController;
                if (null != tabbarController)
                {
                    tabbarController.ViewControllerSelected += OnTabbarControllerItemSelected;
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
        }

        private async void OnTabbarControllerItemSelected(object sender, UITabBarSelectionEventArgs eventArgs)
        {
            if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
            {
                await _page.CurrentPage.Navigation.PopToRootAsync();
            }

        }
    }
}
like image 102
Kyle Avatar answered Nov 04 '22 03:11

Kyle


Do some research of Android Native TabLayout the click event call back function is OnTabReselected

And according to the TabbedPageRenderer source code. You can find OnTabReselected is not be implemented.

So I created a customer render for TabbedPage as following code and implement the OnTabReselected function to change the current page background :

[assembly: ExportRenderer(typeof(Page1), typeof(MyTabPageRender))]
namespace XamarinTabbedPage_Demo.Droid
{
    public class MyTabPageRender : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
    {
        protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
        {
            base.OnElementChanged(e);
        }
        void TabLayout.IOnTabSelectedListener.OnTabReselected(TabLayout.Tab tab)
        {
            int selectedIndex = tab.Position;
            if (Element.Children.Count > selectedIndex && selectedIndex >= 0)
            {
                Element.CurrentPage = Element.Children[selectedIndex];

                if (selectedIndex == 0)
                {
                    Element.CurrentPage.BackgroundColor = Color.Black;
                }
            }
        }
    }
}

enter image description here

like image 4
Mike Ma Avatar answered Nov 04 '22 03:11

Mike Ma