Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing CustomRender for TabbedPage

I have a Tabbed page on my Xamarin Forms project. The tabs used to slide around but I have implemented a CustomRender to stop this.

This works great, except for when I need to re-add a page to the tab bar. I can't seem to re-use the custom render?

Right now I'm re-adding a page to the CustomRendered TabbedPage like so:

var masterTabPage = this.Parent.Parent as NoSlideTabbedPage;

Xamarin.Forms.NavigationPage Page1 = new Xamarin.Forms.NavigationPage(new Page1("example string"));
Page1.Title = "Page Example";
Page1.Icon = "pageexample.png";

masterTabPage.Children.RemoveAt(1);
masterTabPage.Children.Insert(1, Page1);

masterTabPage.CurrentPage = masterTabPage.Children[1];

My layout page looks like

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Layout : NoSlideTabbedPage
{
    public Layout()
    {
        InitializeComponent();

        On<Android>().SetBarItemColor(Color.FromHex("#cccccc"));
        On<Android>().SetBarSelectedItemColor(Color.FromHex("#123456"));

        // SET NAV BAR TO BOTTOM
        On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);

        // CREATE TABS
        NavigationPage Page0 = new NavigationPage(new Page0());
        Page0.Title = "Page0";
        Page0.Icon = "Page0.png";

        NavigationPage Page1 = new NavigationPage(new Page1());
        Page1.Title = "Page1";
        Page1.Icon = "Page1.png";

        NavigationPage Page2 = new NavigationPage(new Page2());
        Page2.Title = "Page2";
        Page2.Icon = "Page2.png";

        NavigationPage Page3 = new NavigationPage(new Page3());
        Page3.Title = "Page3";
        Page3.Icon = "Page3.png";

        // ADD TABS
        Children.Add(Page0);
        Children.Add(Page1);
        Children.Add(Page2);
        Children.Add(Page3);
    }
}

Code for CustomRenderer:

public class NoSlideTabbedPageRenderer : TabbedPageRenderer
{
    private bool _isShiftModeSet;

    public NoSlideTabbedPageRenderer(Context context)
        : base(context)
    {

    }

    protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        base.OnLayout(changed, l, t, r, b);
        try
        {
            if (!_isShiftModeSet)
            {
                var children = GetAllChildViews(ViewGroup);

                if (children.SingleOrDefault(x => x is BottomNavigationView) is BottomNavigationView bottomNav)
                {
                    bottomNav.SetShiftMode(false, false);
                    _isShiftModeSet = true;
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error setting ShiftMode: {e}");
        }
    }

    private List<View> GetAllChildViews(View view)
    {
        if (!(view is ViewGroup group))
        {
            return new List<View> { view };
        }

        var result = new List<View>();

        for (int i = 0; i < group.ChildCount; i++)
        {
            var child = group.GetChildAt(i);

            var childList = new List<View> { child };
            childList.AddRange(GetAllChildViews(child));

            result.AddRange(childList);
        }

        return result.Distinct().ToList();
    }
}

The layout page works, as I'm using the CustomRender above. This allows the tabbar to be normal. However when I remove and re-add a page (show in the first code block), the CustomRender stops being used. How can I maintain use of this custom render whilst still re-adding this Page1?

like image 278
Matt Ward Avatar asked Jul 22 '26 08:07

Matt Ward


1 Answers

You can listen to the element changed property and call the shiftmode again.

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

        if(e.NewElement !=null)
        {
             var children = GetAllChildViews(ViewGroup);

            if (children.SingleOrDefault(x => x is BottomNavigationView) is BottomNavigationView bottomNav)
            {
                bottomNav.SetShiftMode(false, false);
                _isShiftModeSet = true;
            }
        }
    }
like image 108
Bruno Caceiro Avatar answered Jul 24 '26 02:07

Bruno Caceiro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!