I’m going to do a little serie of smaller tricks I recently came across when doing Mono for Android development.

For the first one, here is a small helper class I’m now using everywhere in place of the standard Android’s ImageView.

I call it FadeImageView and it’s simply a wrapper around the former that implements an automatic fade-out/fade-in effect when changing pictures.

This class comes from a realization I had inspired by @migueldeicaza and various other people in the field that animation can be more than a gimmick.

At the same time, I think the best UI animations are the ones your users don’t notice because they feel natural.

The FadeImageView class is exactly in that line of thought, animation here is used to provide a smooth transition for the user eyes between, let’s say, a placeholder image and the actual result bitmap an user expects to see e.g. something you download. The animation itself is actually not that important.

Without further ado, following is the code:

using System;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Android.Graphics;
using Android.Views.Animations;
using Android.Graphics.Drawables;

namespace Foo
{
	public class FadeImageView : ImageView
	{
		Animation fadeInAnimation;
		Animation fadeOutAnimation;

		public FadeImageView (Context ctx) : base (ctx)
		{
			Initialize ();
		}

		public FadeImageView (Context context, IAttributeSet attrs) :
			base (context, attrs)
		{
			Initialize ();
		}

		public FadeImageView (Context context, IAttributeSet attrs, int defStyle) :
			base (context, attrs, defStyle)
		{
			Initialize ();
		}

		void Initialize ()
		{
			fadeInAnimation = new AlphaAnimation (0, 1) {
				Duration = 500
			};
			fadeOutAnimation = new AlphaAnimation (1, 0) {
				Duration = 100
			};
		}

		void DoAnimation (bool really, Action changePic)
		{
			if (!really)
				changePic ();
			else {
				EventHandler<Animation.AnimationEndEventArgs> callback = (s, e) => {
					changePic ();
					StartAnimation (fadeInAnimation);
					fadeOutAnimation.AnimationEnd -= callback;
				};
				fadeOutAnimation.AnimationEnd += callback;
				StartAnimation (fadeOutAnimation);
			}
		}

		public void SetImageBitmap (Bitmap bm, bool animate)
		{
			DoAnimation (animate, () => SetImageBitmap (bm));
		}

		public void SetImageDrawable (Drawable drawable, bool animate)
		{
			DoAnimation (animate, () => SetImageDrawable (drawable));
		}

		public void SetImageResource (int resId, bool animate)
		{
			DoAnimation (animate, () => SetImageResource (resId));
		}

		public void SetImageURI (Android.Net.Uri uri, bool animate)
		{
			DoAnimation (animate, () => SetImageURI (uri));
		}
	}
}

To use it, replace occurence of ImageView with FadeImageView (directly in XML layout or in code). To activate the animation, simply use the overload accepting a boolean.