我是Xamarin的新手,想要创建一个具有多个页面的应用程序,这些页面通过按钮点击导航到。 我已经研究了如何通过代码导航到所需的页面,但我很难隐藏标签以禁止用户导航。
我使用TabbedPage有我的主页,然后添加8个NavigationPages作为孩子。
如何隐藏标签?
答案 0 :(得分:3)
要隐藏Xamarin.Forms中的标签,您需要在本机项目中包含自定义渲染器。我没有与UWP合作,所以只是发布iOS和Android的渲染器,他们完全隐藏了标签栏。 更改我的命名空间并考虑可能是选项卡页面的子类,这样您就不会隐藏应用程序中的所有选项卡,只会隐藏选定的选项卡。
iOS渲染器:
using System;
using AppoMobi.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using UIKit;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(HiddenTabbedPageRenderer))]
namespace AppoMobi.iOS
{
//***************************************************************************
public class HiddenTabbedPageRenderer : TabbedRenderer
//***************************************************************************
{
private UITabBarController tabbarController { get; set; }
private TabbedPage CurrentTabbedPage { get; set; }
//-------------------------------------------------------------
protected override void OnElementChanged(VisualElementChangedEventArgs e)
//-------------------------------------------------------------
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
//release any stuff here
}
if (e.NewElement != null)
{
tabbarController = (UITabBarController) this.ViewController;
CurrentTabbedPage = (TabbedPage) e.NewElement;
}
else
{
CurrentTabbedPage = (TabbedPage) e.OldElement;
}
//the following commented code is not working
//as Forms as it just leaves empty white space
//instead of hidden tabbedbar:
// if (tabbarController != null)
// tabbarController.TabBar.Hidden = true;
}
//just hide tabbar by setting its height to zero
// credits:
// https://stackoverflow.com/a/26255545/7149454
// "how to change UITabBar height"
private nfloat newHeight = 0; //change tabbed bar height to this value
//-------------------------------------------------------------------
public override void ViewWillLayoutSubviews()
//-------------------------------------------------------------------
{
if (tabbarController != null)
{
var tabFrame = tabbarController.TabBar.Frame; //self.TabBar is IBOutlet of your TabBar
tabFrame.Height = newHeight;
tabFrame.Offset(0, tabbarController.View.Frame.Height - newHeight);
tabbarController.TabBar.Frame = tabFrame;
}
base.ViewWillLayoutSubviews();
}
}
}
Android渲染器:
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using System;
using Android.Content;
using Android.Support.Design.Widget;
using Android.Support.V4.View;
using Android.Views;
using AppoMobi.Droid;
using Xamarin.Forms.Platform.Android.AppCompat;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedRenderer))]
namespace AppoMobi.Droid
{
//****************************************************
public class MyTabbedRenderer : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
//****************************************************
{
private TabLayout TabsLayout { get; set; }
private ViewPager PagerLayout { get; set; }
private NiftyTabbedPage CurrentTabbedPage { get; set; }
//-------------------------------------------------------------------
public MyTabbedRenderer(Context context) : base(context)
//-------------------------------------------------------------------
{
}
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
//cleanup here
}
if (e.NewElement != null)
{
CurrentTabbedPage = (NiftyTabbedPage)e.NewElement;
}
else
CurrentTabbedPage = (NiftyTabbedPage)e.OldElement;
//find the pager and tabs
for (int i = 0; i < ChildCount; ++i)
{
Android.Views.View view = (Android.Views.View)GetChildAt(i);
if (view is TabLayout)
TabsLayout = (TabLayout)view;
else
if (view is ViewPager) PagerLayout = (ViewPager)view;
}
}
//-------------------------------------------------------------------------------
protected override void OnLayout(bool changed, int l, int t, int r, int b)
//-------------------------------------------------------------------------------
{
TabsLayout.Visibility = ViewStates.Gone;
base.OnLayout(changed, l, t, r, b);
}
}
}
答案 1 :(得分:0)
我喜欢ZaneCampbell提供的here解决方案。它可以工作,很简单,不需要自定义渲染器。用他自己的话说:
我只是将TabbedPage嵌入到NavigationPage中,然后将选项卡添加到TabbedPage中时,我将动作传递给必要的选项卡,从而允许他们将页面推入NavigationPage。经过测试,可在iOS和Android上使用。
然后是代码:
public class TabControllerPage : TabbedPage
{
public TabControllerPage()
{
// This hides the navigation page's navigation bar as it is not needed
NavigationPage.SetHasNavigationBar(this, false);
// Create tab page and pass PushPage action to it
var testPage = new TestPage {
PushPage = (page) => {
Navigation.PushAsync(page, true);
}
};
// Add as many tabs as you like here
AddTab(testPage, "Tab 1", true, "tab_1_icon.png");
}
void AddTab(Page page, string title, bool inNav, string icon = null)
{
// This sets the NavigationBar title
page.Title = title;
if (inNav)
{
var navigationPage = new NavigationPage(page);
if (icon != null)
{
navigationPage.Icon = icon;
}
// This sets the tab labels
navigationPage.Title = title;
Children.Add(navigationPage);
}
else
{
Children.Add(page);
}
}
}
public partial class TestPage : ContentPage
{
public Action<ContentPage> PushPage;
public TestPage()
{
InitializeComponent();
}
// Call this method when ever you need to push a page onto the navigation page and hide the tabbed page.
void NavigateToPage(ContentPage page)
{
PushPage?.Invoke(page);
}
}
答案 2 :(得分:0)
您只需执行以下操作即可删除或隐藏不需要的页面。
this.Children.Remove(Page you want to remove);
答案 3 :(得分:0)
在我的自定义渲染器中,我能够像这样隐藏标签导航栏。
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
tabbedPage = e.NewElement as Xamarin.Forms.TabbedPage;
bottomNavigationView = (GetChildAt(0) as Android.Widget.RelativeLayout).GetChildAt(1) as BottomNavigationView;
bottomNavigationView.NavigationItemSelected += BottomNavigationView_NavigationItemSelected;
//Call to change the font
ChangeFont();
}
if (e.OldElement != null)
{
bottomNavigationView.NavigationItemSelected -= BottomNavigationView_NavigationItemSelected;
}
bottomNavigationView.Visibility = ViewStates.Gone;
}
答案 4 :(得分:-1)
如何隐藏标签?
在我看来,你不应该。
对于您所描述的导航方案,选项卡式页面在技术上和UX方面都不是正确的方法。
实现所需导航方案的最简单方法可能是使用NavigationPage
(请参阅here和here)并通过设置HasNavigationBar
隐藏导航栏属性false
// in App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new FirstPage())
{
HasNavigationBar = false;
};
}
您可以在自己的网页上访问Application.Current
,获取NavigationPage
并导航
public void Button_OnPress(object sender, EventArgs e)
{
var navigationPage = Application.Current.MainPage as NavigationPage;
if(navigationPage != null)
{
navigationPage.PushAsync(new WhatEverPage());
}
}
备注:虽然可以这样做,但这并不意味着你应该这样做。我强烈建议使用像Prism这样的MVVM框架,并使用棱镜INavigationService
进行导航。通过这种方式,您可以保持页面松散耦合,因为INavigationService
不会占用页面实例,而是使用其名称并使用DI容器解析它们。