Issue
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.
Solution
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?.
Answered By - Leo Zhu - MSFT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.