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?
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;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With