好吧,经过几个小时我终于弄清楚了。它分为三个部分。
#1 处理 Android 上的硬件后退按钮。这个很简单,重写 OnBackButtonPressed 即可。请记住,这仅适用于硬件后退按钮和 Android。它不会处理导航栏后退按钮。正如您所看到的,我试图在退出页面之前通过浏览器返回,但是您可以放入您需要的任何逻辑。
protected override bool OnBackButtonPressed()
{
if (_browser.CanGoBack)
{
_browser.GoBack();
return true;
}
else
{
//await Navigation.PopAsync(true);
base.OnBackButtonPressed();
return true;
}
}
#2 iOS 导航后退按钮。这确实很棘手,如果您环顾网络,您会发现几个用新的自定义按钮替换后退按钮的示例,但几乎不可能让它看起来像其他页面一样。在本例中,我制作了一个位于普通按钮顶部的透明按钮。
[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);
}
}
}
安卓,比较麻烦。在旧版本和未来版本的 Forms 一旦修复后,您可以简单地覆盖 OnOptionsItemselected,如下所示
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 中以设置工具栏:
Android.Support.V7.Widget.Toolbar toolbar = this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
可是等等!如果您的 .Forms 版本太旧或太新,则会出现工具栏为空的错误。如果发生这种情况,我按照最后期限完成工作的方式就是这样的。在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);
};
ArticleDetail 是一个 Page,而 androidAction 是一个Action
如果我的页面上的平台是 Android,我会在 OnAppearing 上运行。此时,在您的应用程序中,工具栏将不再为空。
再加上几个步骤,我们上面制作的 iOS 渲染使用的属性需要添加到要为其制作渲染器的任何页面中。我是为了我的MyAdvantagePage
我制作的类,它实现了 ContentPage 。所以在我的MyAdvantagePage
我添加的类
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
我可以添加这个
:
this.EnableBackButtonOverride = true;
this.CustomBackButtonAction = async () =>
{
if (_browser.CanGoBack)
{
_browser.GoBack();
}
else
{
await Navigation.PopAsync(true);
}
};
这应该是让它在 Android 硬件上恢复工作以及在 Android 和 iOS 上恢复导航的一切。