如何更改xamarin表单中的导航页面后退按钮

时间:2017-11-16 06:50:29

标签: android xamarin xamarin.forms navigation toolbar

我正在尝试更改导航页面中的后退箭头图像。为此在Android应用程序中我创建了导航页面渲染器,然后使用方法toolbar.SetNavigationIcon并且它不起作用,但是当我使用toolbar.SetLogo时其工作正常。

    protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
    {

        base.OnElementChanged(e);
        toolbar.SetNavigationIcon(Resource.Drawable.arrow); 
        toolbar.SetLogo(Resource.Drawable.arrow);
    }
    public override void OnViewAdded(Android.Views.View child)
    {
        base.OnViewAdded(child);
        if (child.GetType() == typeof(Android.Support.V7.Widget.Toolbar))
        {
            toolbar = (Android.Support.V7.Widget.Toolbar)child;
            toolbar.ChildViewAdded += Toolbar_ChildViewAdded;
        }
    }

我还尝试在toolbar.axml中将app添加到app:navigationIcon,它在设计器中显示效果很好 my arrow

但是,当我启动我的应用程序时,我有相同的标准箭头图标 enter image description here

2 个答案:

答案 0 :(得分:4)

如果您的MainActivityFormsApplicationActivity,则可以参考此示例:

https://github.com/jessejiang0214/ChangeBackIconInXF/tree/master/Droid

如果您的MainActivity类型为FormsAppCompatActivity,则可以自定义PageRenderer并更改Toolbar的{​​{1}}。

例如:

NavigationIcon

用法:

[assembly: ExportRenderer(typeof(ContentPage), typeof(NavigationPageRendererDroid))]
...
public class NavigationPageRendererDroid : PageRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
    {
        base.OnElementChanged(e);

        var context = (Activity)Xamarin.Forms.Forms.Context;
        var toolbar = context.FindViewById<Android.Support.V7.Widget.Toolbar>(Droid.Resource.Id.toolbar);

        toolbar.NavigationIcon = Android.Support.V4.Content.ContextCompat.GetDrawable(context, Resource.Drawable.Back);
    }
}

Effect

更新:

当您使用MainPage = new NavigationPage(new MainPage()); ... //When click a button in MainPage, navigate to another page private async void Button_Clicked(object sender, EventArgs e) { await Navigation.PushAsync(new TestPage()); } 方法导航到其他页面时,系统会自动更新Navigation.PushAsync()的图标,您可以在source code中找到:

Toolbar

解决方案:

因此我们别无选择,只能自定义protected virtual Task<bool> OnPushAsync(Page view, bool animated) { return SwitchContentAsync(view, animated); } Task<bool> SwitchContentAsync(Page page, bool animated, bool removed = false, bool popToRoot = false) { ... UpdateToolbar(); ... } void UpdateToolbar() { ... bool isNavigated = ((INavigationPageController)Element).StackDepth > 1; if (isNavigated) { ... if (NavigationPage.GetHasBackButton(Element.CurrentPage)) { //Set the navigation back icon < =================== !!! =-= var icon = new DrawerArrowDrawable(activity.SupportActionBar.ThemedContext); icon.Progress = 1; bar.NavigationIcon = icon; } } ... } ,覆盖NavigationPageRenderer方法以设置OnPushAsync的图标。

Toolbar

using AToolbar = Android.Support.V7.Widget.Toolbar; [assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(NavigationPageRendererDroid))] // APPCOMP ... public class NavigationPageRendererDroid : Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer // APPCOMP { public AToolbar toolbar; public Activity context; protected override Task<bool> OnPushAsync(Page view, bool animated) { var retVal = base.OnPushAsync(view, animated); context = (Activity)Xamarin.Forms.Forms.Context; toolbar = context.FindViewById<Android.Support.V7.Widget.Toolbar>(Droid.Resource.Id.toolbar); if (toolbar != null) { if (toolbar.NavigationIcon != null) { toolbar.NavigationIcon = Android.Support.V4.Content.ContextCompat.GetDrawable(context, Resource.Drawable.Back); //toolbar.SetNavigationIcon(Resource.Drawable.Back); } } return retVal; } } 中定义了CustomNavigationPage

PCL

用法:

public class CustomNavigationPage : NavigationPage
{
    public CustomNavigationPage(Page startupPage) : base(startupPage)
    {
    }
}

答案 1 :(得分:0)

我在下一个方面解决了这个问题: 在我的MainActivity中,我添加了静态工具栏属性,并在OnCreateOptionsMenu中识别它

    public static Toolbar ToolBar { get; private set; }

    public override bool OnCreateOptionsMenu(IMenu menu)
    {
        ToolBar = FindViewById<Toolbar>(Resource.Id.toolbar);
        ToolBar.SetNavigationIcon(Resource.Drawable.arrow);
        return base.OnCreateOptionsMenu(menu);
    }

    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;
        ....
    }

然后在PageRenderer:

protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
     base.OnElementChanged(e);
     MainActivity.ToolBar?.SetNavigationIcon(Resource.Drawable.arrow);
}

但是!!从2种方式我有不好的effect重绘

用法:

async void tapImage_Tapped(object sender, EventArgs e)
{
     await Navigation.PushAsync(new ChooseGenrePage(_listGenres));
}