我正在尝试使用andoid的BottomNavigationView
在Xamarin Forms跨平台应用程序中制作类似iOS的标签页,方法是在android项目中制作一个特定于平台的渲染器。基本上我添加了一个带有bottomnavigationview的布局,并在渲染器中将此视图添加到根活动,并基于窗体选项卡页面创建菜单项。现在问题是如何将表单选项卡页面的当前页面添加/显示到android布局,并在单击条形图项时替换它。我发现即使我在渲染器中调用RemoveAllViews
,选项卡页面中的内容页面也会占据整个屏幕,它甚至会覆盖底部栏。因此,如果选项卡页面的任何一个内容页面可见,它将占据整个屏幕。 android的AddView
方法也只接受android视图,它不接受表单视图。
BottomNav布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
android:layout_above="@+id/bottom_navigation"
android:orientation="vertical">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="@color/colorPrimary"
android:background="@color/colorPrimary"
app:itemIconTint="@color/white"
app:itemTextColor="@color/white"
app:menu="@menu/bottom_navigation_main" />
</RelativeLayout>
渲染器OnElementChanged:
base.OnElementChanged(e);
TabbedPage oe = e.OldElement;
TabbedPage ne = e.NewElement;
int id = 1000;
foreach(Page p in ne.Children)
{
items.Add(new Item
{
text = p.Title,
icon = p.Icon,
page = p,
id = id++,
});
p.IsVisible = false; // without this, page show full screen and covers the bottom bar
}
RemoveAllViews();
Activity activity = this.Context as Activity;
view = activity.LayoutInflater.Inflate(Resource.Layout.BottomNav, this, false);
AddView(view);
layout = view.FindViewById<FrameLayout>(Resource.Id.rootLayout);
// add current page to layout, or replace layout with page? and How?
//
//
BottomNavigationView bottomNavigationView = (BottomNavigationView)
FindViewById(Resource.Id.bottom_navigation);
bottomNavigationView.NavigationItemSelected += BottomNavigationView_NavigationItemSelected;
Android.Support.V7.View.Menu.MenuBuilder menu = bottomNavigationView.Menu as Android.Support.V7.View.Menu.MenuBuilder;
menu.Clear();
foreach(Item i in items)
{
IMenuItem mi = menu.Add(0, i.id, 0, i.text);
mi.SetIcon(Resource.Drawable.icon);
}
编辑:添加更多代码和屏幕截图
我的预期布局是这样的,没有显示XF标签页中的页面,红色的主要部分是标识为FrameLayout
的{{1}},目标是添加标签页的当前页面到Framelayout并显示它,当点击BottomNavigationView中的项目时,切换FrameLayout以显示其他页面。但是这个屏幕只能通过以下方式使所有页面不可见:
rootLayout
我的测试XF标签页:
foreach (Page p in e.NewElement.Children)
{
p.IsVisible = false;
}
答案 0 :(得分:1)
根据您的说明,我认为您根本不需要TabbedPage
,您只需要BottomNavigationView
和FrameLayout
视图片段。然后,您可以为此自定义ViewRenderer
。
首先,在PCL中创建View
的子类,例如:
public class BottomTabbedView:View
{
}
然后在android客户端项目中实现其渲染器:
[assembly:ExportRenderer(typeof(BottomTabbedView),typeof(BottomTabbedViewRenderer))]
namespace PackageNameSpace.Droid
{
public class BottomTabbedViewRenderer:ViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (Control == null)
{
// Instantiate the native control and assign it to the Control property with
// the SetNativeControl method
var context = Xamarin.Forms.Forms.Context;
LayoutInflater inflater = context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater;
var bottomnav_view = inflater.Inflate(Resource.Layout.bottomnav_view, this, false);
var frame = bottomnav_view.FindViewById<FrameLayout>(Resource.Id.rootLayout);
var navi = bottomnav_view.FindViewById<BottomNavigationView>(Resource.Id.bottom_navigation);
SetNativeControl(bottomnav_view);
}
if (e.OldElement != null)
{
// Unsubscribe from event handlers and cleanup any resources
}
if (e.NewElement != null)
{
// Configure the control and subscribe to event handlers
}
}
}
}
我没有完成BottomNavigationView
和FrameLayout
逻辑的所有代码,您应该能够在ViewRenderer
内实现逻辑。代码应该类似于Xamarin.Android的代码。
然后你可以将这个视图用作XF ContentPage
内的普通视图控件,例如:
<local:BottomTabbedView/>