question

EJ-5254 avatar image
0 Votes"
EJ-5254 asked LeonLu-MSFT commented

Android WebViewRenderer height

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.

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered LeonLu-MSFT edited

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.


· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Leon,

Thank you for your help. My problem is not with disabling WebView scrolling as my code above does disable it, but when WebView is inside ScrollView it doesn't display content if it's longer than screen height (only issue on Android).

If I move WebView outside ScrollView then it displays all content. I'm trying to figure out why Android WebView doesn't load full content when inside ScrollView and scrolling is disabled for WebView?

I've also tried your code to see if it makes any difference, but same result.

0 Votes 0 ·

You can try to use StackLayout to wrap the Scrollview like following code.

<StackLayout>
        <ScrollView>
        <WebView HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"  Source="https://dotnet.microsoft.com/apps/xamarin/"/>

        </ScrollView>
    </StackLayout>
0 Votes 0 ·

Fantastic, thank you so much, StackLayout did the trick, wasted so many hours thinking problem was in the Android render! :(

0 Votes 0 ·
Show more comments
EJ-5254 avatar image
0 Votes"
EJ-5254 answered LeonLu-MSFT commented

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.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If you have another issue, you can open a new thread for it, in this way, it will make answer searching in the forum easier and be beneficial to other community members as well.

0 Votes 0 ·