Reputation: 20738
I want to make a layout like this:
I am using Shell with Tab (no Flyout for now) and I don't know how I can achieve this. I tried creating a Page but obviously it doesn't work:
<ContentPage.Content>
<StackLayout>
<root:AppShell />
<Label Text="My Content" />
</StackLayout>
</ContentPage.Content>
Is there a way to wrap the content/Shell with something? Also it's preferably that that content should be above the Tabs but it's okay to be below as well.
Upvotes: 0
Views: 332
Reputation: 15011
You could use Shell CustomRender to achieve this.
Create TodoTabBar
in the forms project:
public class TodoTabBar : TabBar
{
public StackLayout BottomLayout { get; set; }
}
then set in the AppShell.xaml
:
<c:TodoTabBar>
<c:TodoTabBar.BottomLayout>
<StackLayout HorizontalOptions="StartAndExpand" HeightRequest="200">
<Label Text="I'm bottomview"></Label>
</StackLayout>
</c:TodoTabBar.BottomLayout>
<Tab ..>
<ShellContent ContentTemplate="..." />
</Tab>
<Tab ...>
<ShellContent ContentTemplate="..." />
</Tab>
</c:TodoTabBar>
create TodoShellRenderer
and TodoShellItemRenderer
in your Android project:
public class TodoShellRenderer : ShellRenderer
{
public TodoShellRenderer(Context context) : base(context)
{
}
protected override IShellItemRenderer CreateShellItemRenderer(ShellItem shellItem)
{
return new TodoShellItemRenderer(this);
}
}
and
public class TodoShellItemRenderer : ShellItemRenderer
{
FrameLayout _shellOverlay;
BottomNavigationView _bottomView;
public TodoShellItemRenderer(IShellContext shellContext) : base(shellContext)
{
}
public override Android.Views.View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var outerlayout = base.OnCreateView(inflater, container, savedInstanceState);
_bottomView = outerlayout.FindViewById<BottomNavigationView>(Resource.Id.bottomtab_tabbar);
_shellOverlay = outerlayout.FindViewById<FrameLayout>(Resource.Id.bottomtab_tabbar_container);
if (ShellItem is TodoTabBar todoTabBar && todoTabBar.BottomLayout != null)
SetupBottomLayout();
return outerlayout;
}
private async void SetupBottomLayout()
{
var todoTabBar = (TodoTabBar)ShellItem;
var layout = new FrameLayout(Context);
var stackLayout = todoTabBar.BottomLayout;
var size = new Rectangle(0, 0, Context.Resources.DisplayMetrics.WidthPixels, stackLayout.HeightRequest);
var vRenderer = RendererFactory.GetRenderer(stackLayout);
var viewGroup = vRenderer.ViewGroup;
vRenderer.Tracker.UpdateLayout();
var layoutParams = new ViewGroup.LayoutParams((int)size.Width, (int)size.Height);
viewGroup.LayoutParameters = layoutParams;
stackLayout.Layout(size);
viewGroup.Layout(0, 0, (int)stackLayout.WidthRequest, (int)stackLayout.HeightRequest);
layout.AddView(viewGroup);
_shellOverlay.RemoveAllViews();
_shellOverlay.AddView(layout);
}
}
the BottomTabLayout.xml
(this is what we should replace the defaul xml,for this to work the IDs in the layout must match exactly what was in the Xamarin Androidn Platform layout):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<LinearLayout
android:layout_above="@id/bottomtab.tabbar.container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/bottomtab.navarea"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="fill"
android:layout_weight="1" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomtab.tabbar"
android:theme="@style/Widget.Design.BottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<FrameLayout
android:id="@+id/bottomtab.tabbar.container"
android:background="#f00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
Inspired by the link from Can I add a static view above the tabbar in Xamarin Forms Shell?.
Upvotes: 0