如何更改 xamarin 表单中的导航页后退按钮
Posted
技术标签:
【中文标题】如何更改 xamarin 表单中的导航页后退按钮【英文标题】:How to change navigation page back button in xamarin forms 【发布时间】:2018-04-29 14:50:57 【问题描述】:我正在尝试更改导航页面中的后退箭头图像。为此,我在 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;
我还尝试在工具栏.axml 中将图像添加到 app:navigationIcon,它在设计器中显示得很好 my arrow
但是,当我启动我的应用程序时,我有相同的标准箭头图标 enter image description here
【问题讨论】:
不,没有帮助 您的MainActivity
类型是什么?
【参考方案1】:
如果你的MainActivity
是FormsApplicationActivity
,你可以参考这个例子:
https://github.com/jessejiang0214/ChangeBackIconInXF/tree/master/Droid
如果您的MainActivity
类型是FormsAppCompatActivity
,您可以自定义PageRenderer
并更改Toolbar
的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);
用法:
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());
Effect.
更新:
当您使用Navigation.PushAsync()
方法导航到另一个页面时,系统会自动更新Toolbar
的图标,您可以在source code 中找到:
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)
用法:
public App()
InitializeComponent();
MainPage = new CustomNavigationPage(new MainPage());
...
// In MainPage
private async void Button_Clicked(object sender, EventArgs e)
await Navigation.PushAsync(new TestPage());
【讨论】:
请检查我的答案 @BogdanSevryukov,我已经更新了我的答案,效果很好,你可以检查一下。 我现在正在使用此示例中的 BoxView link 它允许我轻松更改所有带有标题的内容页面的高度、图标、字体系列背景渐变 :) 谢谢你的回答 :)它将在未来 100% 帮助我【参考方案2】:我通过以下方式解决了这个问题: 在我的 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));
【讨论】:
我已经更新了我的答案来解决这个重绘问题,希望这可以帮助你。 :)以上是关于如何更改 xamarin 表单中的导航页后退按钮的主要内容,如果未能解决你的问题,请参考以下文章
创建自定义导航栏渲染器以在 xamarin 表单 IOS 项目中添加自定义后退按钮图标