Xamarin.forms: [Enhancement] Android: TabbedPage: Bottom Tab Bar

Created on 26 Jan 2018  ·  89Comments  ·  Source: xamarin/Xamarin.Forms

Rationale

The latest android Material Design guidelines talk about a bottom navigation bar.
https://material.io/guidelines/components/bottom-navigation.html#

Implementation

Expose a switch on the TabbedPage that causes it to render on android using BottomNavigationView.

public static class TabbedPage
{
    public static readonly BindableProperty UseBottomNavigation;

    public static bool GetUseBottomNavigation(BindableObject element);
    public static void SetUseBottomNavigation(BindableObject element, bool value);

    public static bool UseBottomNavigation(
        this IPlatformElementConfiguration<Android, FormsElement> config
    );
    public static IPlatformElementConfiguration<Android, FormsElement> SetUseBottomNavigation(
        this IPlatformElementConfiguration<Android, FormsElement> config, 
        bool value
    );
}

Expected Result

TabbedPage is rendered with BottomNavigationView.

Implications for CSS

None.

Backward Compatibility

None.

Difficulty : Moderate

Either the mapping is natural so its easy, else we shouldn't shove it into a TabbedView and we need to revisit the design.

F100 community-sprint Android enhancement ➕

Most helpful comment

@maherzaidoune not yet.
I had looked into a little bit for initial implementation but decided to leave it for the next version.

Just to be clear you're talking about this right?
https://stackoverflow.com/questions/41649494/how-to-remove-icon-animation-for-bottom-navigation-view-in-android

All 89 comments

Related #1400

Hi, I just opened a pull request on this issue. I have a few questions about the implementation, but it is a starting point.
The mapping was obvious enough.

I am reallly looking forward this pull-request being merge into Xamarin Forms. Is there an E.T.A or something. I haven't found any viable solution to have tabbed page at the bottom on Android.

@mikescandy any update on this?

Finally, I am looking farword to this so long!
Thank you so much!

When will this enhancement roll out?

+1
can I get it on nightly build? cc @PureWeen @davidortinau

And how does it work? Can we set it in the XAML of our Forms app as well (as a property of the TabbedPage)?

@netonjm I think it's just a prop "UseBottomNavigation" https://github.com/mikescandy/Xamarin.Forms/blob/27c6da20b0ade7f96c0fd889f00c96b7e4db1fcc/Xamarin.Forms.Platform.Android/AppCompat/TabbedPageRenderer.cs#L60

but not really sure of the details (icons and colours).

It's me :-)

oops

So by setting "UseBottomNavigation" in XAML it will show the tabbar at the bottom on Android and iOS (like it already does for a TabbedPage), right?

Awesome :D! Is this enhancement already part of the latest pre-release NuGet package? And if not, any ETA on this?

@niels9001 and @PureWeen I've installed xamarin forms 3.1.0.506097 upgrading for version 2. Seems to be working now but am i right in thinking this isn't available there yet?

Any chance anybody could explain the process of when cards (on the done closed column etc) get merged into the nightly from here https://github.com/xamarin/Xamarin.Forms/projects/2#card-8921124?

Also how does this this board relate? https://github.com/xamarin/Xamarin.Forms/projects/6

thanks!

ok went through the pull requests and ended up doing this to get it to work on xamarin.forms

private Xamarin.Forms.TabbedPage __bottomBarPage;
        private INavigationService __navigationService;
        private Page __currentPage;

        public BottomTabBarPageBuilder(INavigationService navigationService)
        {
            __navigationService = navigationService;
            __bottomBarPage = new Xamarin.Forms.TabbedPage();
            __bottomBarPage.BarTextColor = (Color)App.Current.Resources["tile2"]; // Setting Color of selected Text and Icon
            __bottomBarPage.On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
            // You can only define the color for the active icon if you set the Bottombar to fixed mode
            //__bottomBarPage.Navigation..FixedMode = true;
        }|

nevermind the my code but the main part is __bottomBarPage.On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(ToolbarPlacement.Bottom); is this the right way?

Yes that's the right way. It's a platform specific thing so just need to set that before the control is rendered.

hey, does this support fixed mode ?! i can't find a way to set it

@maherzaidoune not yet.
I had looked into a little bit for initial implementation but decided to leave it for the next version.

Just to be clear you're talking about this right?
https://stackoverflow.com/questions/41649494/how-to-remove-icon-animation-for-bottom-navigation-view-in-android

I'm a bit puzzled. Where are we supposed to set the ToolBarPlacement?

`namespace Test.Mobile.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestPage : Xamarin.Forms.TabbedPage
{

    public Test()
    {
        InitializeComponent();

        On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);

    }`

Like this?

@PureWeen How does On<Android>().SetElevation(); work? I tried to set it with some float value but I do not see any effect. I wanted to drop some shadow to distinguish between page content and the bottom bar.

@niels9001 yes

Is that working for you ok?

@PureWeen Nope, I'm getting this error in the MainPage.xaml.g.cs (which is a MasterDetail view, and the TabbedPage is in the Detail part of that)

Unhandled Exception:
System.TypeLoadException: Could not resolve type with token 0100008e (from typeref, class/assembly Xamarin.Forms.PlatformConfiguration.AndroidSpecific.ToolbarPlacement, Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null) occurred

I am amazed. Brilliant. @PureWeen Thanks so much for this.

@PureWeen Please let me know if I can help with the Badge implementation.

@niels9001 that error usually means something is out of sync with the libraries. Can you delete all your obj/bin folders and make sure you have the same version of Xam Forms installed everywhere?

https://forums.xamarin.com/discussion/83410/could-not-resolve-type-with-token-01000012

@PureWeen Thanks, that worked :)!

How do we set the background color of the entire bar? Or enable a dropshadow?

If the child page (tab) of the bottom TabbedPage is a NavigationPage then it, and its contents (ContentPage with ScrollView), is rendered underneath the tab bar. (3.1-pre3)

Nice work!
But why 5 children is the max? It crashes when I try to add more.

Oh I see. Thank you!
Thats sad :/

Yea, I went back and forth with the best way to help the user with that. If you look there's a GetMaxCount you can call which right now just returns a 5 for the bottom tabs and a max int for top tabs. I'll look to see if I can propagate a more useful error message :-)

@bdgza

Thank you for reporting. I've created an issue for this
https://github.com/xamarin/Xamarin.Forms/issues/2993

@PureWeen BarBackgroundColor doesn't seem to work to change the background color of the bar when placed at the Bottom on Android?

@niels9001 do you have a reproduction for that by chance?

I tested and for me it works

image

hey, is it possible to disable that animation when switching pages ? I dont mean icon animation but that transition animation

edit: also I would like to ask If I want latest changes of this, should I use nightly builds or prerelease ? because it seems like pre4 is newer than current nighlty build

@dstarec a new nightly for 3.2 is up on myget

Currently there is not but what you're asking is for this
https://github.com/xamarin/Xamarin.Forms/issues/2948
right?

@PureWeen
yes, it seems like it is

@PureWeen
How do I disable Shift Mode on this?

I've pulled in James' code here from here: https://montemagno.com/remove-shifting-bottomnavigationview-android/

Added a custom renderer for Android, but I can't call it like this, because I don't know the Id of the bottom navigation view:

var bottomNavigation = FindViewById(Resource.Id.bottom_navigation);
bottomNavigation.SetShiftMode(false, false);

EDIT:
The only way I've been able to do it so far is to recursively loop through the Views in ViewGroup to find the BottomNavigationView.

Any solution for removing shifting mode ?

@LynoDesu @amrkamal1993 will address in an upcoming release
https://github.com/xamarin/Xamarin.Forms/issues/3083

@amrkamal1993 I have gotten around it by using a custom renderer. I'll post my code later when I'm home

@amrkamal1993 @maherzaidoune
See gist here:
https://gist.github.com/LynoDesu/64904b6d143892cf14a60a32798a36bb

@LynoDesu How Can i implement disable shift mode ? i Used your code but no thing changed

How have you implemented it? With my code, you need to use the custom control BottomNavTabPage instead of the TabbedPage:

<?xml version="1.0" encoding="utf-8" ?> <controls:BottomNavTabPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:views="clr-namespace:MyProject.App.Views;assembly=MyProjects.App" xmlns:controls="clr-namespace:MyProject.App.Controls;assembly=MyProjects.App" x:Class="MyProject.App.Views.MainTabPage" Title=""> <views:NewsFeed></views:NewsFeed> <views:Rewards></views:Rewards> <views:Nominations></views:Nominations> <views:Notifications></views:Notifications> </controls:BottomNavTabPage>

disabledshiftmode

How can I add Badge Text in bottom tab ?

@LynoDesu thx it works finally !! ^_^

@nhdanh https://github.com/xabre/xamarin-forms-tab-badge
this may help you :)

@amrkamal1993 : thank you, but I try this plugin. It not add badge text when I use Bottom bar.

@nhdanh tab is still the same as top one it should work with the new feature .. bottom tab placement

@amrkamal1993 when I set On().SetToolbarPlacement(ToolbarPlacement.Bottom). It not render Badge text. I remove this setting bottom. It will display Badge text

anything else about badge text ?

@LynoDesu Awesome! Your solution just helped made my day! Thanks!

I tried to update Xamarin.Forms to the latest version and I get this error when I try to set the ToolbarPlacement in my TabbedPage class:

Unhandled Exception:

System.TypeLoadException: Could not resolve type with token 01000029 (from typeref, class/assembly Xamarin.Forms.PlatformConfiguration.AndroidSpecific.ToolbarPlacement, Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null) ocurrió

I dont know what im doing wrong, I think this error is related to the versions of the nuget packages. What can I do to resolve it?

@aalbendin that will happen if something is out of date or just quite isn't building the correct libraries. I would recommend deleting all your bin/obj folders and then rebuilding your project and that should fix it.

A user further up was having the same issue and that resolved it for them

https://github.com/xamarin/Xamarin.Forms/issues/1675#issuecomment-395211876

is this available on stable 3.1.0.583944 version? I have added the On

Anyone else trying to hide the TabbedNavigationBar? I am having an issue on Android if I set the VisibiltyStates.Gone to the BottomNavigationView the view is not completely dismissed:

screen shot 2018-07-05 at 2 14 26 pm

@15mgm15 that issue is semi related to
https://github.com/xamarin/Xamarin.Forms/issues/3055

The ViewPager that displays the content accounts for the height of the bottom navigation bar so that content doesn't get hidden behind it. In order for that content to be taken up again it has to re-layout the viewpager but there's nothing right now that watches for that visibility and change

What's your use case? Could you instead Push a Modal page onto the stack so that it just overlays the entire screen instead of trying to hide the bottom nav bar?

@PureWeen Thanks for the response! unfortunately using modal pages breaks the client design, so I will have to find a solution.

@15mgm15 if you use a top nav bar does it do the same thing? Or does this only happen with the bottom nav bar?

@PureWeen Actually that is good point let me check and let you know.

@PureWeen Using the normal tav bar everything works as expected, the TabLayout of the TabbedPageRenderer is hidden or showed as we pleased. But I tried setting the height to 0 on the layout parameters and it actually worked!

BottomNavigationView _bottomBar;
...
if (_extendedTabbedPage.BottomTabBarHidden) { _layoutParams.Height = 0; _bottomBar.LayoutParameters = _layoutParams; } else { _layoutParams.Height = _bottomBarHeight; _bottomBar.LayoutParameters = _layoutParams; }

Hey that's good to hear!! Once https://github.com/xamarin/Xamarin.Forms/issues/3055 gets fixed I'm hoping that will smooth out some of the rough parts a bit

@cassionandi are you still having issues? If you set the navbar location in your constructor or use XAML you shouldn't be having any issues

If you do not set a label, and only the icon, the icons are not center aligned vertically. It looks weird, like there is a label missing.

Is this expected behaviour? Would be nice if the icons would be in the center (like the Outlook app on Android).

I think I'm missing something. I updated Xamarin Forms to release 3.1.0.583944 but I get two errors on the line On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);

The name ToolbarPlacement' does not exist in the current context

and

Error CS1061: 'IPlatformElementConfiguration' does not contain a definition for 'SetToolbarPlacement' and no extension method 'SetToolbarPlacement' accepting a first argument of type 'IPlatformElementConfiguration' could be found

any suggestions?

@bverp

using Xamarin.Forms.PlatformConfiguration.AndroidSpecific

?

If anyone wants to override the OnTabReselected event or wants to add badges to the tabs or wants to hide the BottomNavigationView here is an example:

https://gist.github.com/15mgm15/76914bf623e33676252864ac1898e7f9

@bverp Close VS, delete the obj and bin folder and restart the project. That should work, atleast it did for me.

@niels9001 that didn't work for me. @bverp did you get it working? I tried downloading and building this project, but get the error: The name ToolbarPlacement' does not exist in the current context
https://github.com/15mgm15/XamarinFormsBottomTabbedPage

I'm doing my nut a bit - does anyone have time to help?
I tried a number of things to get bottom tabs in Android, including both options in this link. Whatever I do, my solution does not recognise the update.
https://developer.xamarin.com/releases/xamarin-forms/xamarin-forms-3.1/3.1.0/
I have forms version 3.1.0.637273 (and have tried the last 5 releases/prereleases too).
I have cleaned, built, rebuilt, deleted the bin/obj directories - I cannot seem to see this update at all no matter what I do.

For example, this is my current XAML

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ProjName"
             x:Class="ProjName.MainPage"
    xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
            android:TabbedPage.ToolbarPlacement="Bottom"
            android:TabbedPage.BarItemColor="Black"
            android:TabbedPage.BarSelectedItemColor="Red">
    <local:LoginPage Title="Favorites" Icon="ic_favorites.png" />
    <local:LoginPage Title="Friends" Icon="ic_friends.png" />
    <local:LoginPage Title="Nearby" Icon="ic_nearby.png" />
    <local:LoginPage Title="Recents" Icon="ic_recents.png" />
    <local:RegistrationPage Title="Restaurants" Icon="ic_restaurants.png" />
</TabbedPage>

and the result is

No property, bindable property, or event found for 'ToolbarPlacement', or mismatching type between value and property.

Similar problem doing it programatically - it simply does not recognise that update.

I'm on Windows VS, using 8.1 Android for testing, and its a shared rather than .net project. If anyone can tell me what I'm missing it would make me very happy.

@pureween?

@taramasalata confirm that all your projects are using the most recent version of 3.1.0. Something is not matching up.

You can also check my sample project here: https://github.com/davidortinau/TheLittleThingsPlayground

I also confirmed I could do the bottom tabs from a shared project without error. Project:
App25.zip

@davidortinau Thank you for helping. I have tried variations of this in 8 different solutions. I have updated all projects to 3.1.0 and triple checked everything. I have checked the "updates" tab for each one repeatedly they are all up to date. I can't think what else to try. I'll try your sample projects in the morning and get back to you. Maybe I should try reinstalling VS.

Your app25 will not build with error : No property, bindable property, or event found for 'ToolbarPlacement', or mismatching type between value and property.

Are you on Windows or Mac?

I'm going to try a complete reinstall of VS now I really cannot think what else to try

Nope. No joy with fresh install, running App25. This is so frustrating.
error: Position 6:13. No property, bindable property, or event found for 'ToolbarPlacement', or mismatching type between value and property.

Are there any packages I need for this beside Xamarin.Forms?

Hmm something in your build tool chain just isn't quite right @taramasalata
Maybe set the build output to verbose to see any messages? Check your Android Sdk make sure you have latest build tools? Install 4.7.1 sdk see if that resolves? delete all your cached Xamarin.forms nugets
c:users.nuget

Use something like ILSpy or dotpeek to look at the dlls in your debug directory and check the version or see if you can find those values in there?

Try a code base approach instead of XAML?

Thank you @pureween. I tried both code based and xaml. I also tried reinstalling VS and tried the "preview" version too. It's likely my uninstall/reinstall didn't delete the .nuget files though. I'll try all your suggestions now.

Having reinstalled all things Android this now works. Thanks so much all!

Quick Q am I correct in thinking this will only run on Android 8.1 up?

Hi @taramasalata. I had a similar issue and it got fixed using the following steps:

  • Deleting all "bin" and "obj" folders of my app
  • Click on "Clean Solution"
  • Restart Visual Studio
  • Click on "Rebuild Solution".

@taramasalata YAY!!!! It should run on any device with at least API 15

In building this I tested against API 15, 19, 23, 27

Getting the tint colors working on 19 and 15 was really fun

@taramasalata yes i got it working after adding using Xamarin.Forms.PlatformConfiguration.AndroidSpecific and restarting VS and cleaning the solution.

When use on Top, works with 6 Childrens. When is at the Bottom, just 5.
The app crashs with the message "Java.Lang.IllegalArgumentException: "

@marcelinhovt yea that's an android limitation.

The BottomNavBar in Android only supports 5 items and there really isn't anyway for us to get around this

@PureWeen oh...i didn´t know. Thanks... I will try to write some render to extend

@marcelinhovt so what I mean is that natively the BottomNavigationBar in android doesn't support more then 5 items. That's not a limitation imposed by our design

There is a way to set elevation on bottom tab bar?

I Have a new problem in android limitation even i have only 5 tabs app is crashing

@amrkamal1993 if you could create a repro and a new issue then we can hopefully address the issue

@PureWeen thank PureWeen , the exception happens when i add title icon in toolbar , i have bottom tab and toolbar , is that a problem which isn't handled

@amrkamal1993 all the test code we have for bottom tab uses icons.

Can you post a repro or code I can test to see if I can recreate the crash?

Was this page helpful?
0 / 5 - 0 ratings