Ответ 1
Хорошо, после многих часов я понял это. Есть три части.
# 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);
}
}
}
Android, сложно. В более ранних версиях и будущих версиях Форм после исправления вы можете просто переопределить 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, вам нужно добавить в свой OnCreate в MainActivity это, чтобы установить панель инструментов:
Android.Support.V7.Widget.Toolbar toolbar = this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
Но подождите! Если у вас слишком старая версия .Forms или слишком новая версия, появляется ошибка, когда панель инструментов имеет значение null. Если это произойдет, взломанный вместе способ, которым я получил работу, чтобы сделать крайний срок, выглядит следующим образом. В OnCreate
в 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 - это страница, androidAction - это Action
, который я запускаю на OnAppearing, если платформа Android на моей странице. К этому моменту вашего приложения панель инструментов больше не будет равна нулю.
Еще несколько шагов, рендеринг 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.