如何在Xamarin Forms中处理/取消后退导航

img*_*gen 15 navigation xamarin xamarin.forms

我试图通过覆盖来使用后退导航OnBackButtonPressed,但不知何故它根本没有被调用.我使用的ContentPage是最新的1.4.2版本.

Kyl*_*yle 22

好吧,经过几个小时,我想出了这个.它有三个部分.

#1处理android上的硬件后退按钮.这个很容易,覆盖OnBackButtonPressed.请记住,这仅适用于硬件后退按钮和Android.它不会处理导航栏后退按钮.正如您所看到的,我在退出页面之前尝试通过浏览器返回,但您可以放置​​所需的任何逻辑.

  protected override bool OnBackButtonPressed()
    {
        if (_browser.CanGoBack)
        {
            _browser.GoBack();
            return true;
        }
        else
        {
            //await Navigation.PopAsync(true);
            base.OnBackButtonPressed();
            return true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

#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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Android,很棘手.在旧版本和未来版本的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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用的是FormsAppCompatActivity,则需要在MainActivity中添加OnCreate以设置工具栏:

Android.Support.V7.Widget.Toolbar toolbar = this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);
Run Code Online (Sandbox Code Playgroud)

可是等等!如果您的.Forms版本太旧或太新版本,则工具栏为空时会出现错误.如果发生这种情况,那么我将其用于制定截止日期的黑客攻击方式就像这样.在OnCreateMainActivity:

        MobileApp.Pages.Articles.ArticleDetail.androdAction = () =>
        {
            Android.Support.V7.Widget.Toolbar toolbar = this.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);
        };
Run Code Online (Sandbox Code Playgroud)

ArticleDetail是一个Page,Action如果我的页面上的平台是Android,则androidAction是我在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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

现在这一切都已完成,MyAdvantagePage我可以添加任何内容

:


 this.EnableBackButtonOverride = true;
            this.CustomBackButtonAction = async () =>
            {
                if (_browser.CanGoBack)
                {
                    _browser.GoBack();
                }
                else
                {
                    await Navigation.PopAsync(true);
                }
            };
Run Code Online (Sandbox Code Playgroud)

这应该是让它在Android硬件上工作的一切,并为Android和iOS导航.


Art*_*nov 13

你是对的,在你的页面类覆盖中OnBackButtonPressed,true如果你想阻止导航,则返回.它适用于我,我有相同的版本.

protected override bool OnBackButtonPressed()
{
    if (Condition)
        return true;
    return base.OnBackButtonPressed();
}
Run Code Online (Sandbox Code Playgroud)

  • [文档](https://developer.xamarin.com/api/member/Xamarin.Forms.NavigationPage.OnBackButtonPressed()/)说"此事件不会在iOS上引发". (3认同)
  • 似乎Xamarin Forms中存在一个错误,即如果我使用TabbedPage作为根页面,那么OnBackButtonPressed将不会被调用.一个看似来自Xamarin的家伙告诉我 (2认同)