Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bottom Tabs for Xamarin.Android (in Xamarin.forms app)

I'm making app with using Xamarin.forms.

You all know regular tabs for Android from Xamarin.forms' TabbedPage is at top. Because it should be there if it's Native Android app that respect Android UX.

But things are changed now. Even Google announced new bottom tab bar called "bottom Navigation". https://github.com/roughike/BottomBar Many major apps're using bottom tab bar.

But I can't use new Bottom Navigation. Because my app is base on Xamarin.forms and uses TabbedPage from forms. It's going to be more complicated if I try to use bottom Navigation.

(I'm making iOS app from forms too)

So Best approach would be moving native Tabs to bottom.

So I found this. (maybe old) http://envyandroid.com/align-tabhost-at-bottom/

But don't know how to use in Xamarin.Android. Could you help me?

like image 349
Bright Lee Avatar asked Dec 01 '22 12:12

Bright Lee


1 Answers

Had ran the same issue, tried to create a custom TabbedPageRenderer from the code present at GitHub but no luck due to several classes and interfaces scoped as internal. Found a solution, a hacky one though, but seems to work fine in our case.

Simply created a new BottomTabbedPage inheriting from TabbedPage so you can link a new Renderer for Android, then create a new Renderer as follows:

[assembly: ExportRenderer(typeof(BottomTabbedPage), typeof(BottomTabbedPageRenderer))]
namespace My.XForms.Droid.Renderers
{
    public class BottomTabbedPageRenderer : TabbedPageRenderer
    {
        protected override void OnLayout(bool changed, int l, int t, int r, int b)
        {
            InvertLayoutThroughScale();

            base.OnLayout(changed, l, t, r, b);
        }

        private void InvertLayoutThroughScale()
        {
            ViewGroup.ScaleY = -1;

            TabLayout tabLayout = null;
            ViewPager viewPager = null;

            for (int i = 0; i < ChildCount; ++i)
            {
                Android.Views.View view = (Android.Views.View)GetChildAt(i);
                if (view is TabLayout) tabLayout = (TabLayout)view;
                else if (view is ViewPager) viewPager = (ViewPager)view;
            }

            tabLayout.ScaleY = viewPager.ScaleY = -1;
            viewPager.SetPadding(0, -tabLayout.MeasuredHeight, 0, 0);
        }
    }
}

Just scaling the page layout and then scaling the children again doesn't make the trick because the original TabbedPageRenderer pads the ViewPager to not to overlap with the TabLayout, so your contained pages would appear with a starting gap so inserting the negative padding fixes that.

Not an ideal solution, just works, but at least you don't run through a full TabbedPage implementation.

like image 66
Pablo López Martínez Avatar answered Dec 05 '22 03:12

Pablo López Martínez