[Android] Enabling scrolling for a WebView inside a ScrollView

RicardoMommRicardoMomm BRMember
edited October 2015 in Xamarin.Forms

I had this problem a while ago and I didn't found a complete solution for this here in the forum so I'm posting a solution using a Custom Renderer that is very simple and worked very well for me and I bet that it should work for other components too. (Eg: ListView inside ScrollView, nested ScrollViews).

I hope others find it useful too.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Droid.CustomRenderers;

[assembly: ExportRenderer(typeof(WebView), typeof(ScrollableWebViewRendererAndroid))]
namespace Droid.CustomRenderers
{

    public class ScrollableWebViewRendererAndroid : WebViewRenderer
    {

        public ScrollableWebViewRendererAndroid()
        {
            System.Diagnostics.Debug.WriteLine("ScrollableWebViewRendererAndroid()");
        }

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

            if (e.OldElement != null)
            {
                Control.Touch -= Control_Touch;
            }

            if (e.NewElement != null)
            {
                Control.Touch += Control_Touch;
            }
        }

        void Control_Touch(object sender, Android.Views.View.TouchEventArgs e)
        {
            // Executing this will prevent the Scrolling to be intercepted by parent views
            switch (e.Event.Action)
            {
                case MotionEventActions.Down:
                    Control.Parent.RequestDisallowInterceptTouchEvent(true);
                    break;
                case MotionEventActions.Up:
                    Control.Parent.RequestDisallowInterceptTouchEvent(false);
                    break;
            }
            // Calling this will allow the scrolling event to be executed in the WebView
            Control.OnTouchEvent(e.Event);
        }
    }
}

Posts

  • Works like a charm

  • ZawYeNaingZawYeNaing USMember

    Thanks Bro. It's Worked.

  • MohammadRezaMohammadReza USMember ✭✭

    hi RicardoMomm
    i have an xamarin android project and there is no xamarin form project
    how can i use this code , i add xamarin.forms component from nuget and create your class "ScrollableWebViewRendererAndroid "
    now how can i use it with android webview in code.
    its part of my code:

    web = FindViewById(Resource.Id.activity_main_webview);
    web.Settings.JavaScriptEnabled = true;

                web.Settings.PluginsEnabled = true;
    
                web.Settings.AllowFileAccess = true;
                web.Settings.JavaScriptCanOpenWindowsAutomatically = true;
                web.Settings.BuiltInZoomControls = true;
                web.Settings.DisplayZoomControls = true;
                web.Settings.SavePassword = true;
                web.Settings.SetRenderPriority(WebSettings.RenderPriority.High);
                web.ScrollBarStyle = ScrollbarStyles.OutsideOverlay; 
    
                web.Settings.LoadWithOverviewMode = true;
                web.Settings.UseWideViewPort = true;
                web.Settings.SetSupportZoom(true);
                web.Settings.DomStorageEnabled = true;
                web.Settings.SetLayoutAlgorithm(WebSettings.LayoutAlgorithm.SingleColumn);
                web.ScrollbarFadingEnabled = true;
                web.SetLayerType(Build.VERSION.SdkInt >= Build.VERSION_CODES.Kitkat ? LayerType.Hardware :LayerType.Software, null);
                web.VerticalScrollBarEnabled = true;
                web.HorizontalScrollBarEnabled = true;
    
                mySwipeRefresh = FindViewById<SwipeRefreshLayout>(Resource.Id.refresher);
                mySwipeRefresh.Refresh += MySwipeRefresh_Refresh;
    
                myWebClient = new MarshalWebViewClient(this);
                web.SetWebViewClient(myWebClient);
    

    .....

  • RicardoMommRicardoMomm BRMember
    edited June 6

    @MohammadReza I think you can take a different approach for Android projects, you can try to mimic the Xamarin Forms Renderer behavior by extending the native WebView class and overriding the OnTouch Event, I don't have it setup to try but it would look something like this:

    public class MyWebView : Android.Webkit.WebView
    {
       ///
       /// ...other required methods
       /// 
    
       public override bool OnTouchEvent(MotionEvent @event)
       {
            RequestDisallowInterceptTouchEvent(true);
            return base.OnTouchEvent(@event);
        }  
    }
    
  • MohammadRezaMohammadReza USMember ✭✭

    @RicardoMomm hi bro my problem not solve in any way , In fact main problem was WebView scrolling lag .....
    i redevelop this project in android studio and java and this scroll lag problem solved.
    Really strange

Sign In or Register to comment.