如何在Xamarin Forms中处理/取消向后导航 [英] How to handle/cancel back navigation in Xamarin Forms

查看:87
本文介绍了如何在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的地方都会出现一个错误.如果发生这种情况,那么我要努力制定一个截止日期的方法就是这样.在MainActivityOnCreate中:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆