Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin Forms, ScrollView ScrollToAsync Speed

Anyone knows how to change the speed of the scroll animation in ScrollToAsync method for Xamarin.Forms.ScrollView control?

I'm developing an Android App with Xamarin Forms. Thanks

like image 389
Luis Ruiz De León Avatar asked Dec 10 '22 08:12

Luis Ruiz De León


2 Answers

Unfortunately, at the time of this writing, the ScrollToAsync speed is hardcoded to 1000 ms (at least for Android).

I was able to work around this by just animating the scroll myself:

Point point = scrollView.GetScrollPositionForElement(targetElement, ScrollToPosition.Start);

var animation = new Animation(
    callback: y => scrollView.ScrollToAsync(point.X, y, animated: false),
    start: scrollView.ScrollY,
    end: point.Y - 6);
animation.Commit(
    owner: this,
    name: "Scroll",
    length: 300,
    easing: Easing.CubicIn);

And here's the documentation for animation.

like image 83
Taylor Lafrinere Avatar answered Jan 03 '23 05:01

Taylor Lafrinere


Modified from Taylor Lafrinere's answer, here is the same snippet as a horizontal scroll animation:

Point point = scrollView.GetScrollPositionForElement(screenContent, ScrollToPosition.Start);

// insert fix for iOS jumping here

var animation = new Animation(
    callback: x => scrollView.ScrollToAsync(x, point.Y, animated: false),
    start: scrollView.ScrollX,
    end: point.X);

animation.Commit(
    owner: this,
    name: "Scroll",
    length: 300,
    easing: Easing.CubicIn);

It is worth pointing out that on iOS, this code displaced the view also towards the top. Something which you do not want. I believe the reason for this is that iOS understands the input for the animation as the lower edge of the scrollview whereas Android understands it as the upper edge of the scrollview.
To avoid this jump, set point.Y to 0 on iOS:

// iOS seems to understand the input for the animation as the lower edge of the scrollview
// Android the upper edge.
if (Xamarin.Forms.Device.RuntimePlatform == Xamarin.Forms.Device.iOS) 
   {
       point.Y = 0;
   }

I still think this answer should have been an edit, but since it was rejected as "Should be an answer or a comment" and it certainly cannot be a comment, here it is as an answer. The intent is to make it more clear that Taylor's Answer covers the vertical animation, and to show how to do a horizontal one instead.

like image 37
lucidbrot Avatar answered Jan 03 '23 03:01

lucidbrot