DEV Community

David Ortinau for .NET

Posted on

Awesome Scroll Effects in Xamarin.Forms

Everyone likes a good parallax scroll effect, right? While that's a good start, you can do so much more once you master the very basic techniques. In this post and video I look at behaviors, converters, and data triggers to add other animation effects and transitions to your UI.

The basis for this example is a reproduction of the Reverb app which I made a long time ago in my Xappy playground app. Navigate to Content\Scenarios\ProductDetails for the completed code.

GitHub logo davidortinau / Xappy

A mobile app to track Xamarin news and explore all the goodness that is .NET for Mobile developers

Getting Scroll Values

Since the scrolling of content is the basis for all the effects in this experience, we need to start with getting values we can bind to. As those values change, we can follow along and trigger other things to happen in the UI.

The easiest way to get values such as the scroll X/Y, relative scroll X/Y, and percentage scroll X/Y is using a behavior from the awesome XAML animation library Xamanimation. Xamanimation is a library that leverages all the built-in APIs of Xamarin.Forms to make complex animations with ease.

Let's start by adding this behavior to our Scrollview:

Parallax Scrolling

To parallax scroll means that the foreground content moves at a different pace than the background (or middle ground) content. Let's start by understanding the layers of this layout.

I'm using a Grid which effectively is a z-stack. The first item in the layout is in the back, then the next stacks on top of it, obscuring it. To then lay things out you'd use columns and rows of different sizes, define any elements to span columns and rows, and the vertical and horizontal options on your children elements. These are the basic points you have to control the layout and achieve any complexity you require.

This is a look at the structure of this layout:

  • Grid
    • BoxView
    • CarouselView
    • ScrollView
    • StackLayout - this is where all of our content resides
    • FlexLayout - navigation bar with no background
    • FlexLayout - navigation bar with white background

As the ScrollView scrolls content, it will appear over the top of the CarouselView. The BoxView just mirrors the CarouselView to leave behind a white background.

Now, in order to move the box and carousel with the content scrolling, we will bind to the scroll behavior's RelativeScrollY and translate the Y position of those views.

If I only used the RelativeScrollY or ScrollY values, the views would translate linear with the content, keeping pace. Instead, I want them to scroll a little slower, thus creating the parallax effect. To do this, I wrote the ScrollValueConverter, a value converter. To tweak the animation effect I pass in several arguments, semi-colon delimited.

The main value of importance here is the "factor" that I use to multiple against the calculated percentage of scroll. The -5 seems like it does nicely.

Animating Other Values with Behaviors

I also want the carousel to fade out as the user scrolls, so for this scenario we can use a Xamarin.Forms behavior, provided again by Xamanimation. This allows you to animate any value based on another value you bind to.

This time I'm using the ScrollY value to change the VisualElement.Opacity to achieve a linear effect. The behavior starts at the Y value 0 and continues until 180 moving the opacity from 1 to 0. Pretty straight forward!

Triggering Animations with Data Triggers

As the user scrolls and the carousel fades out, the navigation bar transitions from transparent background to solid, AND shifts the icons from white to dark. This can be accomplished in several ways, but I chose to do it by duplicating the navigation bar. As the user reaches a certain scroll point, a fade in/out animation is triggered.

This takes advantage of data triggers in Xamarin.Forms. The value of ScrollY is evaluated against criteria I've set to determine a boolean result. When true the EnterActions are called, and when false the ExitActions.

I wrote another value converter, ComparisonConverter, to take a Y position and compare it to my parameter. The parameters are a position value and a comparison rule; in this case, greater than. As the value crosses that boundary, the animations are called.

Xamanimation brings animation extensions from C# to XAML. In this case, I've defined the animations to be triggered in my page resources:

Final Polish

As the content scrolls out of view and back into view it scales away and fades. This happens linearly to the scroll position and at a certain Y position. Since we did this already with the behavior above, this same technique may be applied to each frame of content within the scroll view.

When the first frame hits a scroll Y of 320 it will scale to 75% and fade out completely by the time it reaches a scroll Y of 400. Simple and beautiful!

Please share any cool user experiences you create using these techniques in your experiments and applications. Enjoy!


GitHub logo davidortinau / Xappy

A mobile app to track Xamarin news and explore all the goodness that is .NET for Mobile developers

Top comments (1)

jesse_clark_012ad6e072f22 profile image
Jesse Clark

In running your demo I've noticed a bug. If I scroll the scrollview all the way to the top, and then scroll it back down again, the image does not return to full opacity. I've attached a picture of screenshots of the simulator before the scrolling up (left), and after the scrolling back down (right). You can see that the rightmost image is much grayer than the original. I can't parse the math well enough to see what's going wrong.
Image description