My page has a margin on the left and right when viewed on a tablet device in landscape mode:
Is there any way that I can add a left and right margin to the tab area also?
My page has a margin on the left and right when viewed on a tablet device in landscape mode:
Is there any way that I can add a left and right margin to the tab area also?
Here, the better approach will be to use Padding instead of Margin. You will see why in a while.
So, to start with the implementation - you will need to harness the power of Custom renderers.
In this specific case, we will need to inherit from ShellRenderer
. Also, there are some differences for Android & for iOS - for Android, you will need to override CreateBottomNavViewAppearanceTracker
and for iOS - CreateTabBarAppearanceTracker
Assuming that you have followed the recommendations and named your Shell AppShell, then the 2 classes will look like this.
Android:
using Android.Content;
using TestShellTabBarMargin;
using TestShellTabBarMargin.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(AppShell), typeof(AppShellRenderer))]
namespace TestShellTabBarMargin.Droid
{
public class AppShellRenderer : ShellRenderer
{
public AppShellRenderer(Context context)
: base(context)
{
}
protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
{
return new MarginedTabBarAppearance();
}
}
}
iOS:
using TestShellTabBarMargin;
using TestShellTabBarMargin.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(AppShell), typeof(AppShellRenderer))]
namespace TestShellTabBarMargin.iOS
{
public class AppShellRenderer : ShellRenderer
{
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new MarginedTabBarAppearance();
}
}
}
Next, you will need to create the appearance classes and inherit from the base classes (Android - ShellBottomNavViewAppearanceTracker
& iOS - ShellTabBarAppearanceTracker
).
NB!: You can also implement their interfaces (Android - IShellBottomNavViewAppearanceTracker
& iOS - IShellTabBarAppearanceTracker
) but this way you will lose all of the styles that you have already applied and then you'll have to set them by hand.
After the classes have been subclassed, the important method is SetAppearance
. ResetAppearance
will also work, but it is invoked in many other cases and we need to change it only once.
Here is how it looks by default on Android:
The proper implementation is to set the left & right paddings of the bottom navigation view like this:
using Android.Support.Design.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
namespace TestShellTabBarMargin.Droid
{
public class MarginedTabBarAppearance : ShellBottomNavViewAppearanceTracker
{
public MarginedTabBarAppearance(IShellContext shellContext, ShellItem shellItem)
: base(shellContext, shellItem)
{
}
public override void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
base.SetAppearance(bottomView, appearance);
bottomView.SetPadding(400, 0, 400, 0);
}
}
}
If we want to set the margins, instead of the paddings, then we can modify the layoutParams of the view like this:
public override void SetAppearance(BottomNavigationView bottomView, ShellAppearance appearance)
{
if (bottomView.LayoutParameters is LinearLayout.LayoutParams layoutParams)
{
layoutParams.SetMargins(400, 0, 400, 0);
bottomView.LayoutParameters = layoutParams;
}
}
However, here it will look like this:
You can go and try to set the parent view's Background color, but the end result will be the same and with the Padding set you won't need to try to fix what is not broken.
For iOS the base flow is the same. The important method is again SetAppearance
and inside it we can modify our UITabBar
.
Unfortunately, I haven't found yet the proper config yet, but I will update my answer when I do. Setting the view's/frame's margins/offsets should do the work, but I suspect that the guys from Xamarin are resetting the values after the method has been executed. I bit of tinkering and trial-and-error need to happen here.
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
namespace TestShellTabBarMargin.iOS
{
public class MarginedTabBarAppearance : ShellTabBarAppearanceTracker
{
public override void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
// Modify tab bar settings
}
}
}
Edit: Setting the items' width & positioning to centered should also work and in fact is working, but only on an iPhone (on Portrait). Like I said, I suspect that the guys from Xamarin are making some updates after our changes.
This should work, but it doesn't:
public override void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
base.SetAppearance(controller, appearance);
var tabBar = controller.TabBar;
tabBar.ItemWidth = 50;
tabBar.ItemPositioning = UITabBarItemPositioning.Centered;
}
NB: Keep in mind that you will need to properly handle orientation changes and probably the device idiom (tablet or phone). According to the returned values, you can only then update the desired offsets.
You should use TabbedPageRenderer on iOS/Android platform to change the TabBar template. For instance, Android it could be TabLayout for Android platform and TabBar for iOS
If you meant the shell tab page the first thing you should do is to implement your own ShellRenderer on platform. After that you need to override CreateTabBarAppearanceTracker method where you'll be able to create and return your own ShellTabBarAppearanceTracker(or ShellTabLayoutAppearenceTracker for Android). After that you implement your ShellTabBarAppearanceTracker using by IShellTabBarAppearanceTracker (for iOS). You can do it like this guy: -Creating ShellTabBar/LayoutAppearanceTracker