Xamarin ItemTemplate和WebView控件

时间:2019-04-30 19:25:01

标签: xamarin xamarin.forms

我正在尝试在ItemTemplate中添加WebView控件并设置行的高度。我知道我无法使用webview控件滚动,因此我需要将高度设置为正确的大小以显示完整的html内容。我创建了一个IValueConverter类,该类可以返回所需的正确高度,但是要返回的高度值取决于内容的长度呢?

  

无论如何,我都可以加载Web视图并获得显示完整内容所需的高度,而我在writeline中获得的高度为-1?

XAML代码

<telerikListView:ListViewTemplateCell>
                        <Grid BackgroundColor="{StaticResource LightBlueColor}"
                              Padding="10">
                            <telerikPrimitives:RadBorder Padding="10"
                                             HorizontalOptions="Fill"
                                             BorderThickness="2"
                                             BorderColor="{StaticResource DarkBlueColor}"
                                             BackgroundColor="White">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*" />
                                        <ColumnDefinition Width="50" />
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                       <!--<RowDefinition Height="*"/>-->
                                        <RowDefinition Height="{Binding AssetItem.Description, Converter={StaticResource DescriptionToHeightConverter}}" />
                                    </Grid.RowDefinitions>

                                    <!--<Grid  Grid.Row="0"  Grid.Column="0">
                                        <HtmlLabelControl:HtmlLabel
                                        Text="{Binding AssetItem.Description}"
                                        HeightRequest="100"/>-->
                                    <WebView HeightRequest="800" MinimumHeightRequest="300"   HorizontalOptions="FillAndExpand">
                                        <WebView.Source>
                                            <HtmlWebViewSource Html="{Binding AssetItem.Description}"/>
                                        </WebView.Source>
                                    </WebView>
                                    <!--</Grid>-->

                                    <!--<WebView Grid.Column="0" Grid.Row="0" HeightRequest="200" HorizontalOptions="FillAndExpand">
                                        <WebView.Source>
                                            <HtmlWebViewSource Html="{Binding AssetItem.Description}"/>
                                        </WebView.Source>
                                    </WebView>-->

                                    <!--<Label Text="{Binding AssetItem.Description}"
                                           TextColor="{StaticResource GrayTextColor}"
                                           Grid.Row="0" 
                                           Grid.Column="0"/>-->
                                    <!--Star-->
                                    <telerikPrimitives:RadPath 
                                                       x:Name="path"
                                                       Grid.Row="0" 
                                                       Grid.Column="1"
                                                       WidthRequest="40"
                                                       HeightRequest="35"
                                                       StrokeThickness="2"
                                                       VerticalOptions="Start"
                                                       Fill="{Binding AssetItem.IsBookmark, Converter={StaticResource FavFillColorConverter}}"
                                                       Stroke="#3e7dc5"
                                                       Geometry="{x:Static telerikInput:Geometries.Star}">
                                        <telerikPrimitives:RadPath.GestureRecognizers>
                                            <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="BookmarkCommand" CommandParameter="{Binding AssetItem.AssetId}" />
                                        </telerikPrimitives:RadPath.GestureRecognizers>
                                    </telerikPrimitives:RadPath>
                                </Grid>


                                <!--</Grid>-->
                            </telerikPrimitives:RadBorder>
                        </Grid>
                    </telerikListView:ListViewTemplateCell>

CS转换器逻辑

 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        var description = value as string;

        //WebView wv = new WebView();

        //wv.Source = description;

        HtmlWebViewSource HtmlSource = new HtmlWebViewSource();
        HtmlSource.Html = description;
        WebView webView = new WebView()
        {
            Source = HtmlSource
        };


        Debug.WriteLine($"Web View Height: {webView.Height}");


        if (!string.IsNullOrEmpty(description))
        {
            if (description.Length == 300)
            {

                return 50;
            }
        }
        return 300;
    }

测试代码

    HtmlWebViewSource HtmlSource = new HtmlWebViewSource();
    HtmlSource.Html = "<html><body><div><h1>MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM</h1></div></body></html>";
    WebView webView = new WebView()
    {
        Source = HtmlSource
    };

    string htmlheight = "";
    Task.Run(async () => {
        try
        {
            htmlheight = await webView.EvaluateJavaScriptAsync("document.body.scrollHeight");
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    });

    //WebView_NavigatedAsync(webView);


    Debug.WriteLine($"Web View Height: {htmlheight}");

1 个答案:

答案 0 :(得分:0)

如果要获取html的高度,则可以使用“自定义渲染器”(Custom Renderer)来实现

  

表格

public MainPage()
{
 InitializeComponent();

  HtmlWebViewSource HtmlSource = new HtmlWebViewSource();
  HtmlSource.Html = @"<html><body>
  <h1>Xamarin.Forms</h1>
  <p>Welcome to WebView.</p>
  </body></html>";



  Webview webView = new Webview()
  {
      WidthRequest = 100,
      HeightRequest = 20,
      Source =HtmlSource
  };

  MessagingCenter.Subscribe<Object, float>(this,"webview_loaded",(sender,value)=>{


     Console.WriteLine(value);  //value is the height of html


  });

   Content = new StackLayout
    {
      Children =
      {
        webView,
      },
      VerticalOptions = LayoutOptions.FillAndExpand,
      HorizontalOptions=LayoutOptions.FillAndExpand

     };


}

在iOS项目中

using Foundation;
using UIKit;
using CoreGraphics;

using xxx;
using xxx.iOS;

using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

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

            if(NativeView!=null)
            {

             //  WeakDelegate = this;

            }



        }

        [Export("webViewDidFinishLoad:")]
        public void LoadingFinished(UIWebView webView)
        {
            string htmlHeight = webView.EvaluateJavascript("document.body.scrollHeight");

            float height = float.Parse(htmlHeight);



            MessagingCenter.Send<System.Object, float>(this, "webview_loaded", height);

        }
    }
}

  

在Android中

using Android.Content;

using Android.Webkit;
using Android.Widget;

using xxx;
using xxx.Droid;
using Java.Lang;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyWebViewRenderer))]
namespace xxx.Droid
{
    public class MyWebViewRenderer:WebViewRenderer
    {

        public MyWebViewRenderer(Context context):base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);

            if(Control!=null)
            {

                Android.Webkit.WebView webview =(Android.Webkit.WebView) Control;
                WebSettings settings = webview.Settings;
                settings.JavaScriptEnabled = true;
                webview.SetWebViewClient(new JavascriptWebViewClient());

            }

        }

    }



    public class JavascriptWebViewClient : WebViewClient

    {

        public override void OnPageFinished(Android.Webkit.WebView view, string url)

        {

            base.OnPageFinished(view, url);

            view.EvaluateJavascript("javascript:document.body.scrollHeight;", new EvaluateBack() );

        }

    }

    class EvaluateBack : Java.Lang.Object, IValueCallback
    {

        public void OnReceiveValue(Java.Lang.Object value)
        {
            string htmlHeight = value.ToString();

            float height = float.Parse(htmlHeight);

            MessagingCenter.Send<System.Object, float>(this,"webview_loaded",height);
        }
    }


}

注意:在您的测试代码中,当html尚未完成加载时会调用该方法,因此结果为-1。