【问题标题】:Detect URL change with Xamarin.Forms Webview and Compare current URL to original URL使用 Xamarin.Forms Webview 检测 URL 更改并将当前 URL 与原始 URL 进行比较
【发布时间】:2019-10-10 09:19:05
【问题描述】:

所以我正在创建一个使用 Xamarin.Forms Webview 的应用程序。我正在尝试检测 URL 何时更改,如果更改,则将原始 URL 与当前 URL 进行比较,然后根据情况显示或隐藏按钮。按钮的目的是返回上一页并继续前进,直到到达其原始目的地。我只希望当用户不在主屏幕上时显示这个“返回”按钮。否则,总是显示。

我已经用 if(webview.cangoback...) 尝试了所有方法,但没有检测到 url 更改。我尝试设置一个等于原始 URL 的字符串并使用 .Equals 来比较 webview.source(这是我目前所在的位置)

我刚开始研究 webviewNavigating 但仍然一无所获。

namespace Webview_Test
{
    public partial class MainPage : ContentPage
    {
        public static string CurrentUrl { get; set; }
        public MainPage()
        {

            InitializeComponent();

            string CurrentUrl = "https://www.google.com/";

            var _webView = new WebView()
            {
                Source = "https://www.google.com/",
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand
            };

            Button BackButton = new Button
            {
                Text = "Go Back",
                BackgroundColor = Color.FromHex("990000"),
                TextColor = Color.White
            };
            BackButton.Clicked += OnBackButtonClicked;

            void OnBackButtonClicked(object sender, EventArgs e)
            {
                _webView.GoBack();
            }


            Grid grid = new Grid
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                RowDefinitions =
                {
                    new RowDefinition { Height = GridLength.Auto },
                    new RowDefinition { Height = GridLength.Auto },
                    new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
                    new RowDefinition { Height = new GridLength(50, GridUnitType.Absolute) },
                    new RowDefinition { Height = new GridLength(15, GridUnitType.Absolute) },
                    new RowDefinition { Height = new GridLength(15, GridUnitType.Absolute) },
                    new RowDefinition { Height = new GridLength(36, GridUnitType.Absolute) }
                },
                ColumnDefinitions =
                {
                    new ColumnDefinition { Width = GridLength.Auto },
                    new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                    new ColumnDefinition { Width = new GridLength(50, GridUnitType.Absolute) },
                    new ColumnDefinition { Width = new GridLength(50, GridUnitType.Absolute) },
                    new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                    new ColumnDefinition { Width = GridLength.Auto }
                }
            };

            grid.Children.Add(_webView, 0, 6, 0, 7);

            if (_webView.Source.Equals(CurrentUrl))
            {
                grid.Children.Remove(BackButton);
            }
            else
            {
                grid.Children.Add(BackButton, 2, 4, 4, 6);
            }

            Content = grid;
        }
    }
}

我的预期结果是主页上没有显示“返回”按钮。但在主页以外的任何页面上,它都应该显示“返回”按钮。从逻辑上讲,如果 OriginalURL = CurrentURL 不显示按钮。 if OriginalURL != CurrentURL 显示按钮。

【问题讨论】:

  • 每次新页面开始加载时都会触发导航事件 - 您尝试过吗?

标签: c# xamarin.forms webview


【解决方案1】:

我在每个平台上创建webView的自定义渲染器来获取webView的当前url,它有点复杂,但最终可以工作。

iOS部分,重写LoadingFinished方法获取当前url:

[assembly: ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))]
namespace App374.iOS
{
    public class MyWebViewRenderer : WebViewRenderer,IUIWebViewDelegate
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement == null)
            {   // perform initial setup
                UIWebView myWebView = (UIWebView)this.NativeView;

                Delegate = new CustomWebViewDelegate(e.NewElement as WebView);
            }
        }
    }

    public class CustomWebViewDelegate : UIWebViewDelegate
    {
        Xamarin.Forms.WebView formsWebView;

        public CustomWebViewDelegate(WebView webView)
        {
            formsWebView = webView;
        }

        public override void LoadingFinished(UIWebView webView)
        {
            var url = webView.Request.Url.AbsoluteUrl.ToString();

            MainPage.CurrentUrl = webView.Request.Url.AbsoluteString;

            MainPage.checkToShowButton();
        }

    }
}

在Android部分,重写OnPageFinished方法获取当前url:

[assembly: ExportRenderer (typeof (MyWebView), typeof (MyWebViewRenderer))]
namespace App374.Droid
{
    public class MyWebViewRenderer : WebViewRenderer
    {
        public MyWebViewRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement == null)
            {
                // lets get a reference to the native control
                var webView = (global::Android.Webkit.WebView)Control;
                webView.SetWebViewClient(new MyWebViewClient());
                webView.SetInitialScale(0);
                webView.Settings.JavaScriptEnabled = true;
            }
        }
    }

    public class MyWebViewClient : WebViewClient
    {
        public override void OnPageFinished(Android.Webkit.WebView view, string url)
        {
            base.OnPageFinished(view, url);

            MainPage.CurrentUrl = url;

            MainPage.checkToShowButton();
        }
    }
}

还有代码隐藏,检查每次导航后是否显示返回按钮:

 public partial class MainPage : ContentPage
    {
        public static string CurrentUrl { get; set; }

        public static MyWebView _webView;

        public static Grid grid;

        public static Button BackButton;


        public MainPage()
        {

            InitializeComponent();

            string CurrentUrl = "https://www.baidu.com/";

            _webView = new MyWebView()
            {
                Source = CurrentUrl,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand
            };


            BackButton = new Button
            {
                Text = "Go Back",
                BackgroundColor = Color.FromHex("990000"),
                TextColor = Color.White
            };

            grid = new Grid
            {
                 //...
            };

            grid.Children.Add(_webView, 0, 6, 0, 7);


            Content = grid;

            checkToShowButton();

            //Button click
            BackButton.Clicked += OnBackButtonClicked;
            void OnBackButtonClicked(object sender, EventArgs e)
            {
                _webView.GoBack();        

                checkToShowButton();

                if (_webView.CanGoBack == false)
                {
                    grid.Children.Remove(BackButton);
                }
            }
        }

        //Check whther to show goBack button
        public static void checkToShowButton()
        {

            if ("https://www.baidu.com/".Equals(MainPage.CurrentUrl) || CurrentUrl == null || CurrentUrl == "")
            {
                grid.Children.Remove(BackButton);
            }
            else
            {

                if (grid != null)
                {
                    grid.Children.Add(BackButton, 2, 4, 4, 6);
                }

            }
        }

    }

    public class MyWebView : WebView { }

我上传了我的整个样本here,您可以查看它。让我知道它是否有效。

注意:我测试了_webView.Navigated,发现它只在第一次加载webView时触发。

 _webView.Navigated += (sender, e) => {

 };

参考:webview-check-when-website-address-changed

【讨论】:

    【解决方案2】:

    您是否尝试过导航事件?我会在下面举一些例子。

    public string OriginalURL = "https://www.stackoverflow.com"
    private async void Webview_Navigating(object sender, WebNavigatingEventArgs e)
    {
       if(e.Url != OriginalURL)
       { 
          //Write code, show the button or use if(webview.CanGoBack){//your code}
       }
    }
    

    【讨论】:

      【解决方案3】:

      可能会迟到,但这很有帮助,简单,快速,没有任何问题。

      var url = await webView.EvaluateJavaScriptAsync("window.location.href");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-07
        • 2015-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        • 2019-01-21
        相关资源
        最近更新 更多