0

I have a Xamarin.Forms App (XF 4.2.0.709249).

I have subclassed Scrollview and created a renderer for it in the Android Project.

I have overridden OnScrollChanged methods and hooked into multiple scroll-changed-listeners but none of them get called when the scrollview is scrolled horizontally.

I noticed that the Xamarin.Forms ScrollViewRenderer for Android internally uses a HorizontalScrollView for horizontal scrolling, might this be missing an implementation to invoke the events/call the overridable methods?

EDIT: I also noticed, that setting an x-value in the renderers ScrollTo(int x, int y) method, does not have any effect on the X-Scrolling. ScrollX inside the renderer stays 0 forever, even tho the XamarinForms Scrolled event sends an updated X coordinate.

Forms Project

public class FormsScrollView : ScrollView { }

public class SomePage : ContentPage {
    public SomePage() {
        //calls native scroll events
        vertScrollView = new FormsScrollView() { Orientation = ScrollOrientation.Vertical, Content = SomeScrollableContent };

        //never calls native scrollevents in renderer
        horizontalScrollView = new FormsScrollView() { Orientation = ScrollOrientation.Horizontal };
        horizontalScrollView.Content = CreateScrollContent(20, StackOrientation.Horizontal);
        Content = horizontalScrollView;
    }

    private StackLayout CreateScrollContent(int amount, StackOrientation ori)
    {
        var sl = new StackLayout() { Orientation = ori };
        for (int i = 0; i < amount; i++)
            sl.Children.Add(new Label() { Text = "Cool Label " + i });
        return sl;
    }
}

Android Project

[assembly: ExportRenderer(typeof(FormsScrollView), typeof(FormsScrollView_Droid))]
namespace Coolio.Droid.Renderers
{
    public class FormsScrollView_Droid: ScrollViewRenderer, Android.Views.View.IOnScrollChangeListener
    {
        private readonly IOnScrollChangeListener _scrollListener;

        public FormsScrollView_Droid(Context context) : base(context)
        {
            _scrollListener = new ScrollListener(this);
            SetOnScrollChangeListener(this);
            SetOnScrollChangeListener(_scrollListener);


             this.ScrollX; //never changes, stays 0 forever
             this.ScrollTo(x, y); //setting x has no effect, however setting y does scroll vertically correctly.
        }

        protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
        {
              //never called on horizontal scroll
        }

        public void OnScrollChange(Android.Views.View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY)
        {
             //never called on horizontal scroll
        }
    }


    public class ScrollListener : Java.Lang.Object, Android.Support.V4.Widget.NestedScrollView.IOnScrollChangeListener
    {
        private readonly FormsScrollView_Droid _scrolli;

        public ScrollListener(FormsScrollView_Droid scrolli)
        {
            _scrolli = scrolli;
        }

        public void OnScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY)
        {
            //never called on horizontal scroll
        }
    }
}
Csharpest
  • 1,258
  • 14
  • 32
  • Can you share your layout in xamarin forms. I test it in my demo,I just put a `ScrollView`, `OnScrollChanged` and `OnScrollChange` was executed. – Leon Nov 22 '19 at 09:14
  • Thank you for your feedback, I updated the layout of my XF Project sample, take a look! – Csharpest Nov 22 '19 at 09:32

1 Answers1

1

Refer to this thread: https://forums.xamarin.com/discussion/62241/problem-setting-on-scroll-listener-to-android-horizontal-scroll-view-class-not-found-exception

I changed the FormsScrollView_Droid like following code.

 public class FormsScrollView_Droid: ScrollViewRenderer, ViewTreeObserver.IOnScrollChangedListener
{
   // private readonly IOnScrollChangeListener _scrollListener;

public FormsScrollView_Droid(Context context) : base(context)
{

        ViewTreeObserver.AddOnScrollChangedListener(this);

   // SetOnScrollChangeListener(_scrollListener);
}


protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
{
    //called on Vertical scroll
}

public void OnScrollChange(Android.Views.View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY)
{

}

  public void OnScrollChanged()
  {
       //called on Horizontal scroll
  }
}

Here is running GIF.

enter image description here

Leon
  • 8,404
  • 2
  • 9
  • 52
  • that looks promising! really cool gif to visualize it hits the breakpoint! I will test tonight, but I will still ask, in case you have the time: can you check if the "ScrollX" property ever changes? Preferrably inside the OnScrollChanged method – Csharpest Nov 25 '19 at 10:00
  • I indeed dont see any change in the ScrollX parameter of the ScrollViewRenderer. It's nice to see the onscrollchanged gets hit, but I have to extract the distance it has scrolled as well... do you have any idea? – Csharpest Nov 25 '19 at 10:34
  • Ok sorry for spam, thanks again for showing me the callback. Sadly ScrollViewRenderers `ScrollX` remains 0 and `ScrollTo(x, y)` does not affect the X-Axis-Scrolling. I would have to open another question for that. – Csharpest Nov 25 '19 at 10:51