Android WebViewRenderer height

EJ 366 Reputation points
2021-05-06T00:31:57.187+00:00

Hi,

I want to set height of Android WebViewRenderer to full height of it's content so it doesn't scroll. In iOS it works fine by setting ScrollView.ScrollEnabled = false and HeightRequest to ScrollView.ContentSize.Height, but on Android while height is set correctly, there is no content outside screen height, just blank space. Any idea why Android doesn't fill content to it's height?

This is my code for Android WebView renderer:

public class CustomWebViewRenderer : WebViewRenderer
    {
        static CustomWebView _xwebView = null;
        WebView _webView;

        public CustomWebViewRenderer( Context context ) : base( context )
        {
        }

        class CustomWebViewClient : Android.Webkit.WebViewClient
        {
            public override async void OnPageFinished( WebView view, string url )
            {
                if (_xwebView != null)
                {
                    int i = 10;
                    while (view.ContentHeight == 0 && i-- > 0) 
                        await System.Threading.Tasks.Task.Delay( 100 );
                    _xwebView.HeightRequest = view.ContentHeight;
                }
                base.OnPageFinished( view, url );
            }
        }

        protected override void OnElementChanged( ElementChangedEventArgs<Xamarin.Forms.WebView> e )
        {
            base.OnElementChanged( e );
            _xwebView = e.NewElement as CustomWebView;
            _webView = Control;

            if (e.OldElement == null)
            {
                _webView.SetWebViewClient( new CustomWebViewClient() );
            }
        }

Edit: worked out that this code works fine, problem happens only if I put custom webview inside ScrollView, then it only loads content for the height of screen, the rest is blank.

<ScrollView>
    <ctrl:CustomWebView>
          <WebView.Source>
                    <HtmlWebViewSource Html="{Binding Email.html}" />
           </WebView.Source>
     </ctrl:CustomWebView>
</ScrollView>

If I move it outside ScrollView then it loads fine, but I also want to have some labels above WebView and whole page should scroll. Any idea why ScrollView cuts WebView contents?

By the way, same XAML works fine with custom iOS WkWebViewRenderer, it loads full html content. Something strange happens with Android.

Developer technologies .NET Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Anonymous
    2021-05-06T02:49:17.927+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    You can add SetOnTouchListener to disable the WebView's scroll event. Here is custom-renderer for webview.

       using Android.App;  
       using Android.Content;  
       using Android.OS;  
       using Android.Runtime;  
       using Android.Views;  
       using Android.Webkit;  
       using Android.Widget;  
       using App94.Droid;  
       using System;  
       using System.Collections.Generic;  
       using System.ComponentModel;  
       using System.Linq;  
       using System.Text;  
       using Xamarin.Forms;  
       using Xamarin.Forms.Platform.Android;  
         
       [assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(CustomWebViewRenderer))]  
       namespace App94.Droid  
       {  
           public class CustomWebViewRenderer : WebViewRenderer  
           {  
               public CustomWebViewRenderer(Context context) : base(context)  
               {  
               }  
               Android.Webkit.WebView _webView;  
         
               protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)  
               {  
                   base.OnElementPropertyChanged(sender, e);  
               }  
               protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)  
               {  
                   base.OnElementChanged(e);  
                   if (e.NewElement != null)  
                   {  
                        
                       Control.SetWebViewClient(new CustomWebViewClient(e.NewElement));  
         
                       Control.SetOnTouchListener(new MyTouchListener());  
                   }  
                     
               }  
           }  
         
           internal class MyTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener  
           {  
               public bool OnTouch(Android.Views.View v, MotionEvent e)  
               {  
                   
                   return (e.Action == Android.Views.MotionEventActions.Move);  
               }  
           }  
         
           internal class CustomWebViewClient : WebViewClient  
           {  
               private Xamarin.Forms.WebView newElement;  
         
                
               public CustomWebViewClient(Xamarin.Forms.WebView newElement)  
               {  
                   this.newElement = newElement;  
               }  
         
               public override async void OnPageFinished(Android.Webkit.WebView view, string url)  
               {  
                   if (newElement != null)  
                   {  
                       int i = 10;  
                       while (view.ContentHeight == 0 && i-- > 0)  
                           await System.Threading.Tasks.Task.Delay(100);  
                       newElement.HeightRequest = view.ContentHeight;  
                   }  
                   base.OnPageFinished(view, url);  
               }  
           }  
       }  
    

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


1 additional answer

Sort by: Most helpful
  1. EJ 366 Reputation points
    2021-05-07T11:00:21.9+00:00

    Hi Leon,

    Having trouble with XAML in iOS, in Android works fine. I need to put everything into CarouselView as per example below:

    <CarouselView 
            ItemsSource="{Binding Emails}" 
            Loop="False"
            CurrentItemChanged="carousel_CurrentItemChanged">
    
            <CarouselView.ItemsLayout>
                <LinearItemsLayout 
                    Orientation="Horizontal"
                    SnapPointsType="MandatorySingle"
                    SnapPointsAlignment="Start" />
            </CarouselView.ItemsLayout>
    
            <CarouselView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <ScrollView>
                            <StackLayout>
                                <Label Text="{Binding subject}"/>
                                <ctrl:CustomWebView x:Name="webView">
                                    <WebView.Source>
                                        <HtmlWebViewSource Html="{Binding html}" />
                                    </WebView.Source>
                                </ctrl:CustomWebView>
                            </StackLayout>
                        </ScrollView>
                    </StackLayout>
                </DataTemplate>
            </CarouselView.ItemTemplate>
        </CarouselView>
    

    On Android height is calculated perfectly, in iOS depending where I place VerticalOptions="FillAndExpand" it's either ~3 times the actual content, or cut of. I've tried setting VerticalOptions on everything - CarouselView, StackLayouts, ScrollView, WebView etc. nothing works.

    Any idea how to fix this? I've no clue how everything calculated in Xamarin so having hard time trying to find a solution.

    Cheers.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.