-
-
Save LynoDesu/64904b6d143892cf14a60a32798a36bb to your computer and use it in GitHub Desktop.
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}"); | |
} | |
} | |
} | |
} |
<?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> |
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!
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">
Thank you for sharing this. Worked like a charm!
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?)
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);
Thanks This made my day
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
Not sure why, but if you get Field "mShiftingMode" not found you can bypass it by modifying the "labelVisibilityMode" directly:
var declaredFields = menuView.Class.GetDeclaredFields();
if (declaredFields.Any(t => t.Name == "mShiftingMode"))
{
var shiftMode = menuView.Class.GetDeclaredField("mShiftingMode");
shiftMode.Accessible = true;
shiftMode.SetBoolean(menuView, enableShiftMode);
shiftMode.Accessible = false;
shiftMode.Dispose();
}
else
{
var visibilityMode = menuView.Class.GetDeclaredField("labelVisibilityMode");
visibilityMode.Accessible = true;
visibilityMode.SetInt(menuView, 1);
visibilityMode.Accessible = false;
visibilityMode.Dispose();
}
Edit: 1 is constant value for: LABEL_VISIBILITY_SELECTED
Ref: https://developer.android.com/reference/com/google/android/material/bottomnavigation/LabelVisibilityMode.html#LABEL_VISIBILITY_LABELED
James-Aidoo Please read this.
https://stackoverflow.com/questions/51342200/cannot-resolve-method-setshiftingmodeboolean-in-bottomnavigationview/51342426
You may be using 28.0.0.1 Android Support package
This helped me in Xamarin native android
<android.support.design.widget.BottomNavigationView
app:labelVisibilityMode="unlabeled"
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
Use item.SetShifting(enableItemShiftMode);
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);
Aren't you supposed to just include the namespace of the extension class ? In this case, "using MyProject.App.Droid.Helpers;" . This will let Visual Studio automatically resolve the extension method from the AndroidHelpers class. That's how extensions are to be used.
FYI
var shiftMode = menuView.Class.GetDeclaredField("mShiftingMode");
This property is not accessible if pro guard obfuscates it. Either edit the pro guard configuration, or just comment it out. The code just below it where each child contents in the tab has item.SetShifting(false) -> will solve the issue for most. In such cases, the swipe from edges will still allow tab switching, but not swipe inside the content. I found that optimal in my use case.
How did you get icons to display like your screenshot in xamarin/Xamarin.Forms#1675 (comment) ?