如何在Xamarin Forms中处理/取消向后导航 [英] How to handle/cancel back navigation in Xamarin Forms
问题描述
我试图通过覆盖OnBackButtonPressed
来使用向后导航,但是以某种方式根本没有被调用.我正在使用ContentPage
和最新的1.4.2版本.
I tried to use the back navigation by overriding OnBackButtonPressed
, but somehow it wasn't get called at all. I am using the ContentPage
and the latest 1.4.2 release.
推荐答案
好了,几个小时后,我发现了这个问题.它分为三个部分.
Alright, after many hours I figured this one out. There are three parts to it.
#1处理Android上的硬件后退按钮.这很简单,重写OnBackButtonPressed.请记住,这仅适用于硬件后退按钮和android.它不会处理导航栏的后退按钮.如您所见,在退出页面之前,我试图通过浏览器进行备份,但是您可以输入所需的任何逻辑.
#1 Handling the hardware back button on android. This one is easy, override OnBackButtonPressed. Remember, this is for a hardware back button and android only. It will not handle the navigation bar back button. As you can see, I was trying to back through a browser before backing out of the page, but you can put whatever logic you need in.
protected override bool OnBackButtonPressed()
{
if (_browser.CanGoBack)
{
_browser.GoBack();
return true;
}
else
{
//await Navigation.PopAsync(true);
base.OnBackButtonPressed();
return true;
}
}
#2 iOS导航后退按钮.这确实很棘手,如果您在网上浏览,您会发现几个用新的自定义按钮替换后退按钮的示例,但是要使其看起来像其他页面几乎是不可能的.在这种情况下,我制作了一个透明按钮,该按钮位于普通按钮的顶部.
#2 iOS navigation back button. This one was really tricky, if you look around the web you'll find a couple examples of replacing the back button with a new custom button, but it's almost impossible to get it to look like your other pages. In this case I made a transparent button that sits on top of the normal button.
[assembly: ExportRenderer(typeof(MyAdvantagePage), typeof
(MyAdvantagePageRenderer))]
namespace Advantage.MyAdvantage.MobileApp.iOS.Renderers
{
public class MyAdvantagePageRenderer : Xamarin.Forms.Platform.iOS.PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
if (((MyAdvantagePage)Element).EnableBackButtonOverride)
{
SetCustomBackButton();
}
}
private void SetCustomBackButton()
{
UIButton btn = new UIButton();
btn.Frame = new CGRect(0, 0, 50, 40);
btn.BackgroundColor = UIColor.Clear;
btn.TouchDown += (sender, e) =>
{
// Whatever your custom back button click handling
if (((MyAdvantagePage)Element)?.
CustomBackButtonAction != null)
{
((MyAdvantagePage)Element)?.
CustomBackButtonAction.Invoke();
}
};
NavigationController.NavigationBar.AddSubview(btn);
}
}
}
Android,非常棘手.一旦修复了旧版和以后的Forms版本,您就可以覆盖这样选择的OnOptionsItem
Android, is tricky. In older versions and future versions of Forms once fixed, you can simply override the OnOptionsItemselected like this
public override bool OnOptionsItemSelected(IMenuItem item)
{
// check if the current item id
// is equals to the back button id
if (item.ItemId == 16908332)
{
// retrieve the current xamarin forms page instance
var currentpage = (MyAdvantagePage)
Xamarin.Forms.Application.
Current.MainPage.Navigation.
NavigationStack.LastOrDefault();
// check if the page has subscribed to
// the custom back button event
if (currentpage?.CustomBackButtonAction != null)
{
// invoke the Custom back button action
currentpage?.CustomBackButtonAction.Invoke();
// and disable the default back button action
return false;
}
// if its not subscribed then go ahead
// with the default back button action
return base.OnOptionsItemSelected(item);
}
else
{
// since its not the back button
//click, pass the event to the base
return base.OnOptionsItemSelected(item);
}
}
但是,如果您使用的是FormsAppCompatActivity,则需要在MainActivity中的OnCreate上添加以下内容以设置工具栏:
However, if you are using FormsAppCompatActivity, then you need to add onto your OnCreate in MainActivity this to set your toolbar:
Android.Support.V7.Widget.Toolbar toolbar = this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
但是等等!如果您的.Forms版本太旧或太新,工具栏为null的地方都会出现一个错误.如果发生这种情况,那么我要努力制定一个截止日期的方法就是这样.在MainActivity
的OnCreate
中:
But wait! If you have too old a version of .Forms or too new version, a bug will come up where toolbar is null. If this happens, the hacked together way I got it to work to make a deadline is like this. In OnCreate
in MainActivity
:
MobileApp.Pages.Articles.ArticleDetail.androdAction = () =>
{
Android.Support.V7.Widget.Toolbar toolbar = this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
};
如果页面上的平台是Android,则
ArticleDetail是一个页面,而androidAction是在OnAppearing上运行的Action
.此时,在您的应用中,工具栏将不再为空.
ArticleDetail is a Page, and androidAction is an Action
that I run on OnAppearing if the Platform is Android on my page. By this point in your app, toolbar will no longer be null.
结合更多步骤,我们上面制作的iOS渲染使用的属性需要添加到您要为其创建渲染器的任何页面上.我正在为实现ContentPage的MyAdvantagePage
类创建它.因此,在我的MyAdvantagePage
课堂上,我添加了
Couple more steps, the iOS render we made above uses properties that you need to add to whatever page you are making the renderer for. I was making it for my MyAdvantagePage
class that I made, which implements ContentPage . So in my MyAdvantagePage
class I added
public Action CustomBackButtonAction { get; set; }
public static readonly BindableProperty EnableBackButtonOverrideProperty =
BindableProperty.Create(
nameof(EnableBackButtonOverride),
typeof(bool),
typeof(MyAdvantagePage),
false);
/// <summary>
/// Gets or Sets Custom Back button overriding state
/// </summary>
public bool EnableBackButtonOverride
{
get
{
return (bool)GetValue(EnableBackButtonOverrideProperty);
}
set
{
SetValue(EnableBackButtonOverrideProperty, value);
}
}
现在一切都完成了,在我的任何MyAdvantagePage
上我都可以添加
Now that that is all done, on any of my MyAdvantagePage
I can add this
:
this.EnableBackButtonOverride = true;
this.CustomBackButtonAction = async () =>
{
if (_browser.CanGoBack)
{
_browser.GoBack();
}
else
{
await Navigation.PopAsync(true);
}
};
这应该是使它能够在Android硬件上运行以及在android和iOS上导航返回的一切.
That should be everything to get it to work on Android hardware back, and navigation back for both android and iOS.
这篇关于如何在Xamarin Forms中处理/取消向后导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!