【问题标题】:Xamarin.Forms multiple WebViews but OnPageFinished only seems to apply to last Webview?Xamarin.Forms 多个 WebViews 但 OnPageFinished 似乎只适用于最后一个 Webview?
【发布时间】:2020-08-30 18:20:56
【问题描述】:

我有一个 ListView,里面有三个单独的 WebView。每个 Webview 都有自己的 HTML 内容。这些 Webview 需要响应式(高度应根据其加载的内容进行调整)。

由于这些 webview 的高度不同,我使用 Javascript 来计算高度。由于某种原因,这在使用多个 webview 时不起作用。它似乎只适用于最后一个。

我不确定发生了什么 - 它似乎多次触发 OnPageFinished 事件,但高度请求大多被忽略。它甚至在没有 Javascript 的情况下也会发生(所以如果我为 heightrequest 硬编码一个设定值)

这是 WebView 的代码:

 public class HybridWebViewLeft : WebView
    {

        public static readonly BindableProperty messageContentProperty =
          BindableProperty.Create(nameof(messageContent), typeof(string), typeof(HybridWebViewLeft), string.Empty);
        public string messageContent
        {
            get { return (string)GetValue(messageContentProperty).ToString(); }
            set { SetValue(messageContentProperty, value); }
        }



        public HybridWebViewLeft()
        {

            HorizontalOptions = LayoutOptions.Fill;
            VerticalOptions = LayoutOptions.FillAndExpand;
            Margin = 0;
            HeightRequest = 10;        
            Source = "";

            this.PropertyChanged += HybridWebViewLeft_PropertyChanged;
        }

        private void HybridWebViewLeft_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {

            if (e.PropertyName.Equals(nameof(messageContent)))
            {

                var htmlSource = new HtmlWebViewSource();
                htmlSource.Html = @"<html>
                                    <head>
                                    <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>
                                    <link rel=""stylesheet"" href=""chatmessage-content.css"">
                                    </head>
                                    <body style=""background-color: #DDDDDD;"">Test1<br>Test2<br>Test3<br>Test4<br>Test5<br>Test6<br>Test7<br>Test8 " + 
                                    "<script>function setresponseandsubmit(content) { console.log(content); CSharp.setresponseandsubmit(content); }</script></body></html>";

                htmlSource.BaseUrl = DependencyService.Get<IBaseUrl>().Get();
                Source = htmlSource;

            }

        }

这是Android上的代码:

       class HybridWebViewLeftClient : WebViewClient
        {
            WebView _webView;

            public async override void OnPageFinished(WebView view, string url)
            {

                try
                {
                    _webView = view;
                    if (_xwebView != null)
                    {
                        view.Settings.JavaScriptEnabled = true;
                        view.Settings.DomStorageEnabled = true;
                        await Task.Delay(100);


                        string result = await _xwebView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");
                        _xwebView.HeightRequest = Convert.ToDouble(result);

                    }
                    base.OnPageFinished(view, url);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"EXCEPTION: {ex.Message}");
                }
            }
        }

_xwebView.HeightRequest 为最后一个 WebView 正确计算,其他两个返回为 null,因此使用初始高度 10。

【问题讨论】:

  • 您是否将三个 webview 放在同一个单元格中?如果能把完整的代码贴在xaml和后面的代码就更好了。
  • 不,它们在单独的单元格中。即使我堆叠 WebView,问题仍然存在
  • 你能分享一个样本,以便我可以在我身边进行测试。您的代码无法让 mt 重现该问题。
  • 我能做到 - 最好的方法是什么?通过github?抱歉,对此还很陌生;)
  • 将示例发布到 github。

标签: xamarin.forms webview xamarin.android


【解决方案1】:

原因:

在您的示例中,您将 WebViews 放在 StackLayout 中。但是,StackLayout 在运行时将不适合其子元素。需要提前设置高度。

解决方案:

你应该使用 Grid 。并且不要忘记设置 ScrollView 的 Scroll Orientation

 <ScrollView Orientation="Both">
    <Grid>


        <Grid.RowDefinitions>

            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />


        </Grid.RowDefinitions>

        <Label Grid.Row="0" Text="Testing multi webviews" BackgroundColor="Pink" HorizontalOptions="FillAndExpand" HeightRequest="50" />

        <custom:HybridWebView  Grid.Row="0" messageContent="1" />
        <custom:HybridWebView  Grid.Row="1" messageContent="2" />
        <custom:HybridWebView  Grid.Row="2" messageContent="3" />
        <custom:HybridWebView  Grid.Row="3" messageContent="4" />
        <custom:HybridWebView  Grid.Row="4" messageContent="5" />
        <custom:HybridWebView  Grid.Row="5" messageContent="6" />

    </Grid>
</ScrollView>

此外,如果您想在同一个页面中放置多个 WebView。最好将 ListView 与 DataTemplate 一起使用。

【讨论】:

  • 将内容放在网格中(使用滚动方向)似乎仍然在做同样的事情:仅在最后一个 webview 上计算高度。我错过了什么吗?
  • 删除行HeightRequest = 20;在public HybridWebView()
  • 你是救生员!太感谢了!我觉得它在最后一个上的工作方式很奇怪,因为我希望它会在所有 webviews 上给出同样的问题。再次感谢您为此付出的时间和精力,我真的很感激!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 2020-01-12
  • 1970-01-01
相关资源
最近更新 更多