在 Xamarin 表单应用程序中使用菜单创建导航栏

我现在正在借助 xamarin 表单 [xaml] using crossplatform portable project template in Visual studio

While designing home page of my application I like to have a design like in a normal android app

https://developer.android.com/training/appbar/index.html 制作一个 android 应用程序

但我使用的是导航栏,主页中使用的代码就像

    public  Homepage()
    {
        InitializeComponent();
        #region toolbar
        ToolbarItem tbi = null;
        if (Device.OS == TargetPlatform.Android)
        {
            tbi = new ToolbarItem("+", "plus", async () =>
            {
                var target_page = new AddStudent();
                await Navigation.PushModalAsync(target_page);
            }, 0, 0);
        }
        ToolbarItems.Add(tbi);
        #endregion             
            this.Title = "Home Page";

    }

它给出了一个带有标题的导航栏和右侧的 + 图标,可以帮助我显示另一个页面

但是我怎样才能设计一个页面,就像链接中发布的那样,左侧有一些菜单项和事件,右侧有一些菜单操作,使用这个 NavBar 。

任何示例或有用的链接?

stack overflow Create Navbar with Menus in Xamarin forms app
原文答案

答案:

作者头像

你听说过 AppCompat 吗?对于初学者,请参阅 this

据我了解,您希望应用程序在 iOS 和 Android 上看起来像使用 Android Material Theme 创建的一样。

您显然需要为导航栏实现 custom renderer 。这意味着您必须为要使用它的每个平台编写导航栏的自定义实现。此外,您需要从 PCL 中编辑其中的一部分。

例如,您可以使用此代码摆脱导航栏上 Xamarin 的默认图标(将其添加到您的 Droid 项目中):

[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationRenderer))]
namespace App.Droid
{
    public class CustomNavigationRenderer : NavigationRenderer
    {

        protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
        {
            base.OnElementChanged(e);
            RemoveAppIconFromActionBar();
        }

        void RemoveAppIconFromActionBar()
        {
            var actionBar = ((Activity)Context).ActionBar;
            actionBar.SetIcon(new ColorDrawable(Color.Transparent.ToAndroid()));
        }
    }
}

对于 PCL 中的每个 UI 对象,每个平台都有一个类比。将 XF 对象转换为本机对象是渲染器的职责。创建对象时,会调用 OnElementChanged 。从那里,您可以访问本机 API 并对 PCL 中不可用的元素进行修改。就像调用 SetIcon 一样(请记住,此代码可能是特定于 Android 的。在大多数情况下,您可能需要复制和修改渲染器才能使其在其他平台上工作)。

为了将按钮添加到操作栏的右侧,我将使用以下 xaml:

<ContentPage.ToolbarItems>
    <ToolbarItem x:Name="btn"
             Text="Mail"
             Icon="btn_icon.png"
             Clicked="BtnClickHandler" />
</ContentPage.ToolbarItems>

而不是简单地用后面的代码备份它,比如处理一个简单的按钮单击时:

private void BtnClickHandler(object sender, EventArgs e)
{
    // handling
}

您可以添加其中的几个。

此外,如果您想将上下文菜单添加到工具栏并希望它的行为类似于原生 android 工具栏,您可能应该阅读一些关于 animation 并自己绘制/动画它的内容,然后使用它来协调它,比如说, AbsoluteLayout

作者头像

对于自定义导航栏,我喜欢隐藏导航栏并制作自己的自定义导航栏。你确实放松了一些便利,然后尺寸就在你身上,但它提供了更多的灵活性。

然后,您可以在 BoxView 中放置一个彩色的 Grid ,然后将按钮添加到 Grid ,将它们放在 BoxView 的顶部。

将导航栏和以下内容隐藏到 ContentPage 的构造函数中:

NavigationPage.SetHasNavigationBar(this, false);

*编辑:这很容易做到。就像我说的,你会创建一个 Grid ,添加一个绿色的 BoxView ,然后在左侧添加一个图标,在右侧添加 3 个图标。

像这样的东西:

<Grid VerticalOptions="Start"
      HorizontalOptions="FillAndExpand">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <BoxView BackgroundColor="Green"
             Grid.Row="0"
             Grid.Column="0"
             Grid.ColumnSpan="5"/>

    <Image Source="hamburger.png"
           Grid.Row="0"
           Grid.Column="0">
        <Image.GestureRecognizer>
            <!-- TODO: Add your gesture stuff -->
        </Image.GestureRecognizer>
    </Image>

    <Label Text="Sheets"
           Grid.Row="0"
           Grid.Column="1"/>

    <Image Source="search.png"
           Grid.Row="0"
           Grid.Column="2">
        <Image.GestureRecognizer>
            <!-- TODO: Add your gesture stuff -->
        </Image.GestureRecognizer>
    </Image>

    <Image Source="folder.png"
           Grid.Row="0"
           Grid.Column="3">
        <Image.GestureRecognizer>
            <!-- TODO: Add your gesture stuff -->
        </Image.GestureRecognizer>
    </Image>

    <Image Source="settingstack.png"
           Grid.Row="0"
           Grid.Column="4">
        <Image.GestureRecognizer>
            <!-- TODO: Add your gesture stuff -->
        </Image.GestureRecognizer>
    </Image>

</Grid>