Native animation effects in Xamarin.Forms

,

Xamarin.Forms (XF) provides a cross platform API for doing animations. This makes it very easy to do simple animations of XF elements. There is, however, a downside. The XF animations do not make use of native platform APIs, rather they animate properties on the XF elements. This can cause significant overhead, since each change to the property will trigger a property changed event that the native render will update the corresponding property on the native UI element. For small simple animations this is fine, but it does not take much before you will notice a significant degradation in performance between the XF animations and animations done with native APIs.

Xamarin.Forms 2.1 introduced effects that can easily be attached to the elements we want to animate. Because this can be done using XAML, this approach also works well if you are following the MVVM pattern. We can use these effects as a bridge to implement our own animations that leverage native platform animations to get true native performance.

Xamarin.Forms PCL project

To begin, we will create an empty page with some content to animate up and down when a button is clicked. In this case the Overlay is half the size of the page, and starts off the bottom of the screen.

Next we need to create the effect to reference in the XAML.

Next we need a property that we can toggle when the button is clicked to initiate the animation. To keep things simple, we will add an attached property to the existing VerticalSlideEffect. This attached property could be defined anywhere, but doing it here keeps all of the related code together.

The click handler for the button simply toggles the attached property on the Overlay.

Finally, we attach the effect to the Overlay.

Xamarin.iOS

The effect on iOS is very straightforward. The effect simply watches for the IsShown attached property to change and then starts the appropriate animation.

The AnimateIn and AnimateOut methods move the native container and then set the corresponding XF property. The built-in renderers on iOS use the VisualElementTracker to update many of the common properties. For the XF TranslationY property, it updates the transform on the UIView’s layer. To match that behavior, the effect animates the same property. After the animation completes, the XF property is set. This will trigger a property changed event and the native renderer will update the native property, but because this is the same property that just finished animating there is no visible change.

Xamarin.Android

The animation effect on Android is very similar to the one for iOS; duplicate parts have been omitted for brevity.
Android requires a bit more setup to perform the same slide animation. The value animator will produce a stream of values that can be used to animate a view. Once again looking at the visual element tracker for Android we see that it updates the TranslationY property on the ViewGroup. This is the property that we will update during the animation. Then, after it completes, update the TranslationY on the XF element.
There is one final difference worth noting. We have to convert the screen pixels to logical pixels when setting the correct value back into the XF element. This is done using the FromPixels method.

Using these effects allows us to easily animate views in and achieve native performance. Encapsulating the animations in the effects allows for the code to be re-used and applied to other elements in the future.

The complete solution can be found here.

Share this story