Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

[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 2018

    @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

  • GeervaniGeervani Member ✭✭

    Great. It works. Is there an IOS version of the renderer.

  • RicardoMommRicardoMomm BRMember ✭✭

    I didn't create an iOS version because according to my tests at the time, iOS supports it natively, did you tested?

  • GeervaniGeervani Member ✭✭

    @RicardoMomm said:
    I didn't create an iOS version because according to my tests at the time, iOS supports it natively, did you tested?

    Thanks. Actually I tested in android device. And its working great. I thought it needs to be implemented on IOS as well. will check on actual iOS device and update

  • Ian123Ian123 GBMember ✭✭

    @RicardoMomm Thank you.

  • EmaEEmaE Member ✭✭

    Hello,
    How do I use the CustomRenderer in the Forms project xaml?

  • kalyanipwrkalyanipwr Member ✭✭

    @RicardoMomm can you please tell how to use that custom renderer in Xamarin forms?> @RicardoMomm said:

    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);
            }
        }
    }
    

    hello @RicardoMomm , Can you please tell how to use this custom renderer in Xamarin forms?

  • RicardoMommRicardoMomm BRMember ✭✭

    Hi @kalyanipwr , you can refer to xamarin documentation on how to use CustomRenderers, more info in the link below, long story short you just need to add this class to your Xamarin.Android project

    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/

  • kalyanipwrkalyanipwr Member ✭✭

    @RicardoMomm said:
    Hi @kalyanipwr , you can refer to xamarin documentation on how to use CustomRenderers, more info in the link below, long story short you just need to add this class to your Xamarin.Android project

    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/

    hello @RicardoMomm, i meant, after adding where and how to use it?

  • RicardoMommRicardoMomm BRMember ✭✭

    Got it @kalyanipwr , so once you add it to your Xamarin.Android (not Xamarin.Forms) project and in the File Properties for this class you have the Build Action set to Compile you are good to go, Xamarin will pick it automatically using the Attribute:

    [assembly: ExportRenderer(typeof(WebView), typeof(ScrollableWebViewRendererAndroid))]

    If you have all this and it is not working, perhaps you could provide some small project sample of how you are setting up and I can take a look for you

  • kalyanipwrkalyanipwr Member ✭✭

    thank you @RicardoMomm , did it successfully.

  • kalyanipwrkalyanipwr Member ✭✭

    @RicardoMomm do you know about how to send MMS from an app functionality in xamarin android. I am working on it from many days, but no luck so far.

  • RicardoMommRicardoMomm BRMember ✭✭

    @kalyanipwr said:
    @RicardoMomm do you know about how to send MMS from an app functionality in xamarin android. I am working on it from many days, but no luck so far.

    I never had to deal with MMS in Android or Xamarin, but I think you can find related questions in this forum and perhaps some ready to use NuGet package (https://www.nuget.org/packages/Android.Mms.PduManagement/)

  • kalyanipwrkalyanipwr Member ✭✭

    hello @RicardoMomm , actually i have used this package also but didn't achieved the MMS sending functionality.

  • ekottekott Member

    5 years after posting, still useful. Good job!

Sign In or Register to comment.