WebView inside ScrollView

asked 2021-05-05T02:51:02.467+00:00
EJ 356 Reputation points

Hi,

I've WebView inside ScrollView together with other controls like labels above WebView. When I scroll only WebView scrolls, how can I make so whole screen scrolls?

<ScrollView>
    <StackLayout VerticalOptions="FillAndExpand">
         <Label Text="Hello"/>
      <WebView VerticalOptions="FillAndExpand">
          <WebView.Source>
              <HtmlWebViewSource Html="{Binding MyHTMLText}" />
          </WebView.Source>
      </WebView>
    </StackLayout>
</ScrollView>

I'm trying to achieve same thing as Gmail app does. What is interesting that in Gmail app when you scroll up scrollbar only appears when email header is completely hidden, so looks like they somehow combined email header controls and WebView, but not in ScrollView.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
4,803 questions
No comments
{count} votes

Accepted answer
  1. answered 2021-05-05T06:55:20.45+00:00

    Hello,

    Welcome to Microsoft Q&A!

    Do you simply want to disable the webview scrolling ? If so you can do it with custom renderer in each platform.

    iOS

       [assembly: ExportRenderer(typeof(WebView), typeof(MyRenderer))]  
       namespace FormsA.iOS  
       {  
           public class MyRenderer : WkWebViewRenderer  
           {  
               protected override void OnElementChanged(VisualElementChangedEventArgs e)  
               {  
                   base.OnElementChanged(e);  
         
                   this.ScrollView.ScrollEnabled = false;  
               }  
           }  
       }  
    

    Android

       [assembly: ExportRenderer(typeof(WebView), typeof(MyRenderer))]  
       namespace FormsA.Droid  
       {  
           class MyWebview  : WebView  
           {  
               public MyWebview(Context context):base(context)  
               {  
         
               }  
         
               public MyWebview(Context context, IAttributeSet att ) : base(context,att)  
               {  
         
               }  
         
               public MyWebview(Context context, IAttributeSet att,int defStyle) : base(context,att,defStyle)  
               {  
         
               }  
         
               protected override void OnScrollChanged(int l, int t, int oldl, int oldt)  
               {  
                   base.OnScrollChanged(l, t, oldl, oldt);  
         
                   ScrollTo(l, 0);  
               }  
         
           }  
         
           class MyRenderer : WebViewRenderer  
           {  
         
               Context _context;  
               public MyRenderer(Context context):base(context)  
               {  
                   _context = context;  
               }  
               protected override Android.Webkit.WebView CreateNativeControl()  
               {  
                   return new MyWebview(_context);  
         
               }  
           }  
       }  
    

    Best Regards,
    Cole Xia


    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. answered 2021-05-06T07:03:42.053+00:00

    Try to get height from JSBridge and set on webview.

    [assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyRenderer))]
    namespace FormsA.Droid
    {
        public class JavascriptWebViewClient : FormsWebViewClient
        {
            public JavascriptWebViewClient(MyRenderer renderer) : base(renderer)
            {
    
            }
    
            public override void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                base.OnPageFinished(view, url);
                view.LoadUrl("javascript:myApp.resize(document.body.scrollHeight)");
            }
        }
    
        public class JSBridge : Java.Lang.Object
        {
            public Xamarin.Forms.WebView _webview;
    
            public JSBridge(Xamarin.Forms.WebView webview)
            {
                _webview = webview;
            }
    
            [JavascriptInterface]
            [Export("resize")]
            public void resize(float height)
            {
    
    
                _webview.HeightRequest = height * MainActivity.Instance.ApplicationContext.Resources.DisplayMetrics.Density ;
            }
        }
    
        public class MyRenderer : WebViewRenderer 
        {
    
            Context _context;
            public MyRenderer(Context context):base(context)
            {
                _context = context;
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
    
                if (e.OldElement != null)
                {
                    Control.RemoveJavascriptInterface("jsBridge");
                }
                if (e.NewElement != null)
                {
                    Control.SetWebViewClient(new JavascriptWebViewClient(this));
                    Control.AddJavascriptInterface(new JSBridge(Element), "myApp");
                    Control.LoadUrl("https://dotnet.microsoft.com/apps/xamarin");
                }
            }
    
        }
    }
    
    
    
    //MainActivity
    
      public static MainActivity Instance;
    
    
            protected override void OnCreate(Bundle savedInstanceState)
            {
                TabLayoutResource = Resource.Layout.Tabbar;
                ToolbarResource = Resource.Layout.Toolbar;
    
                base.OnCreate(savedInstanceState);
    
                Instance = this;  add this line
    

    Refer to https://stackoverflow.com/a/25187094/8187800 .

    No comments