Awaitable Animations on Android

A tiny extension method allows you to await Android animations

Posted by Sven-Michael Stübe on September 20, 2016

Xamarin has done a great job on bringing async/await to animations on iOS (as Kerry shows on his blog) and on Xamarin.Forms. For my Fingerprint Plugin I was playing around with some animations on Android and I expected to find a similar animation extension - but I did not (If I’ve overseen something, tweet me). But, awaiting animations is pretty easy with a small extension method.


I want to colorize a icon, animate it and remove the color after the animation. In another use case I want to animate the icon and close the dialog afterwards.


The Android way would be to implement a IAnimatorListener, set the color in its OnAnimationStart method and reset it in OnAnimationEnd. But with this approach the code isn’t readable linearly and you would have to implement a IAnimatorListener for each use case. I wanted to write my Animation like this:

var shake = ObjectAnimator.OfFloat(_icon, "translationX", -10f, 10f);
shake.SetInterpolator(new CycleInterpolator(5));
await shake.StartAsync();

You only need these two classes and are ready to animate Android with C# style.


The AnimatorExtensions only contains the StartAsync method that you should use to start a animation. It adds a TaskAnimationListener as listener, starts the animation and returns the a Task. The method can be used with all Animator classes (e.g. ObjectAnimator, AnimatorSet, ValueAnimator)

public static class AnimatorExtensions
    public static Task StartAsync(this Animator animator)
        var listener = new TaskAnimationListener();
        return listener.Task;


The TaskAnimationListener implements IAnimatorListener and uses a TaskCompletionSource to convert the events OnAnimationCancel and OnAnimationEnd to the Canceled or Completed states of a Task.

public class TaskAnimationListener : Java.Lang.Object, Animator.IAnimatorListener
    private readonly TaskCompletionSource<int> _tcs;
    public Task Task => _tcs.Task;

    public TaskAnimationListener()
        _tcs = new TaskCompletionSource<int>();

    public void OnAnimationCancel(Animator animation)

    public void OnAnimationEnd(Animator animation)

    public void OnAnimationRepeat(Animator animation)

    public void OnAnimationStart(Animator animation)


Found a typo? Send me a pull request!