Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Disable ShiftMode in Xamarin.Forms Android BottomNavigationView
using System;
using Android.Support.Design.Internal;
using Android.Support.Design.Widget;
namespace MyProject.App.Droid.Helpers
{
public static class AndroidHelpers
{
public static void SetShiftMode(this BottomNavigationView bottomNavigationView, bool enableShiftMode, bool enableItemShiftMode)
{
try
{
var menuView = bottomNavigationView.GetChildAt(0) as BottomNavigationMenuView;
if (menuView == null)
{
System.Diagnostics.Debug.WriteLine("Unable to find BottomNavigationMenuView");
return;
}
var shiftMode = menuView.Class.GetDeclaredField("mShiftingMode");
shiftMode.Accessible = true;
shiftMode.SetBoolean(menuView, enableShiftMode);
shiftMode.Accessible = false;
shiftMode.Dispose();
for(int i = 0; i < menuView.ChildCount; i++)
{
var item = menuView.GetChildAt(i) as BottomNavigationItemView;
if (item == null)
continue;
item.SetShiftingMode(enableItemShiftMode);
item.SetChecked(item.ItemData.IsChecked);
}
menuView.UpdateMenuView();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Unable to set shift mode: {ex}");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace MyProject.App.Controls
{
public class BottomNavTabPage : TabbedPage
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android.AppCompat;
using View = Android.Views.View;
[assembly: ExportRenderer(typeof(BottomNavTabPage), typeof(BottomNavTabPageRenderer))]
namespace MyProject.App.Droid.Renderers
{
public class BottomNavTabPageRenderer : TabbedPageRenderer
{
private bool _isShiftModeSet;
public BottomNavTabPageRenderer(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();
}
}
}
<?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>
@greenec

This comment has been minimized.

Copy link

greenec commented Jun 22, 2018

How did you get icons to display like your screenshot in xamarin/Xamarin.Forms#1675 (comment) ?

@greenec

This comment has been minimized.

Copy link

greenec commented Jun 22, 2018

I managed to work it out using the following:

<controls:BottomNavTabPage.Children>
        <NavigationPage Icon="social.png" Title="Social">
            <x:Arguments>
                <views:SocialNewsDetail />
            </x:Arguments>
        </NavigationPage>

        <NavigationPage Icon="links.png" Title="Links">
            <x:Arguments>
                <views:NavigationLinksDetail />
            </x:Arguments>
        </NavigationPage>

        <NavigationPage Icon="messages.png" Title="Messages">
            <x:Arguments>
                <views:MessagesDetail />
            </x:Arguments>
        </NavigationPage>

        <NavigationPage Icon="settings.png" Title="Settings">
            <x:Arguments>
                <views:SettingsDetail />
            </x:Arguments>
        </NavigationPage>
</controls:BottomNavTabPage.Children>

Thanks for the great sample!

@LynoDesu

This comment has been minimized.

Copy link
Owner Author

LynoDesu commented Jun 25, 2018

No problem, glad it was able to help you and sorry that I didn't reply, I didn't get any notification that you commented on the code!

It looks like you already found the answer, but you can also set it in the actual code of the page if you wanted like this:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyProject.App.Views.Rewards"
             Icon="RewardIcon.png">
@cassionandi

This comment has been minimized.

Copy link

cassionandi commented Oct 15, 2018

Thank you for sharing this. Worked like a charm!

@swapnil591

This comment has been minimized.

Copy link

swapnil591 commented Oct 24, 2018

Error on below line
bottomNav.SetShiftMode(false, false);

'BottomNavigationView' does not contain a definition for 'SetShiftMode' and no extension method 'SetShiftMode' accepting a first argument of type 'BottomNavigationView' could be found (are you missing a using directive or an assembly reference?)

@JoacimWall

This comment has been minimized.

Copy link

JoacimWall commented Nov 14, 2018

Hi i also get

bottomNav.SetShiftMode(false, false);

'BottomNavigationView' does not contain a definition for 'SetShiftMode' and no extension method 'SetShiftMode' accepting a first argument of type 'BottomNavigationView' could be found (are you missing a using directive or an assembly reference?)
Change this
bottomNav.SetShiftMode(false, false);
to
Helpers.AndroidHelpers.SetShiftMode(bottomNav, false, false);

@aman720gupta

This comment has been minimized.

Copy link

aman720gupta commented Feb 9, 2019

Thanks This made my day

@James-Aidoo

This comment has been minimized.

Copy link

James-Aidoo commented Feb 20, 2019

item.SetShiftingMode(enableItemShiftMode);

"'BottomNavigationItemView' does not contain a definition for 'SetShiftingMode' and no accessible extension method 'SetShiftingMode' accepting a first argument of type 'BottomNavigationItemView' could be found (are you missing a using directive or an assembly reference?)"

I get the above error in the AndroidHelpers Class.. What am I doing wrong please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.