Spinners are dead. Go Shimmers! A shimmer is a modern unobtrusive loading indicator for full pages or list items. I’ll show you how to add one to your Xamarin application in 10mn.
Xamarin is the leading cross platform native technology to build native apps on android, ios, ipados, tizen, watchs, windows and mac using an unified open source (MIT) language called C#, used in many client and server applications. Needs a hands on lab ? Contact me on email@example.com
Source code and links are in the appendix at the bottom of this article.
- The inglorious shimmer
- The recipe
- Design of a nice shimmer
The inglorious shimmer
You still see a lot of spinners in apps if you are not using your fiber connection at home (i have a very good one) and the app simply waits while its data is fetched over the network. Spinners are a waste of time for the user as he is staying, stuck, looking his phone, waiting like a coconut to fall of its tree.
Instead, it should display like this:
There are 3 important things braught by a shimmer:
- The user sees that the app is not frozen. This prevents an impatient user to kill and uninstall the app early if your data server or the network is a bit slow.
- While there is no data displayed, the layout/shape of how the data will appear on screen once its ready is visible. The user’s eyes can look straight at the places where the information will appear, and start building a mind mapping of what is expected.
- The hypnotizing animation completes this small gain of time for the user’s brain. He now feels safe and confortable. If it was a spinner, he would feel annoyed and full of questions, even maybe feared.
And it’s as easy as 1,2,3 to add to your app.
Both recipes use a placeholder layout that mimics the final layout. An “IsReady” boolean is used to show/hide the placeholder layout and start/stop the shimmering animation, and the same boolean, inverted, is used to show/hide the real layout.
The animation itself is very fast, and works well in a list’s cell.
Unless you create custom renderers for the codes below, you may use this nuget. Check the documentation for its usage. I have not tried it myself.
Android steps — Xamarin native
- Add Xamarin.Facebook.Shimmer from nuget
- Add a com.facebook.shimmer.ShimmerFrameLayout control to your layout (it is a frame layout)
- Create a sublayout in this ShimmerFrameLayout with the placeholder content
- Call Show() or Hide() on the shimmer object at initialization and after the IsReady value has changed.
Note: Hide() does not hide the FrameLayout. It only stops the shimmer animation. You must show/hide the shimmer layout by yourself.
iOS steps — Xamarin native
- Add the ShimmerExtensions.cs file (see below)
- Create a placeholder layout in a container view that will shimmer
- Call containerView.ConfigureShimmer() to get a shimmer object and start/stop the animation using this code:
Note: SetIsShimmering() does not show nor hide the control. It only starts and stops the shimmer animation. You must show/hide the control by yourself.
If you use Mvvmcross, you can use a binding to display the shimmer:
The code for the Shimmering target binding is in the appendix. Register it in your Setup.cs using its Register() method.
Designing a nice shimmer
A shimmer can be seen as a placeholder for real data. For example this shimmer:
can be a good placeholder for this data:
For white backgrounds, a good shimmer placeholder color is #d6d7dc
The shimmer animation will make this color darker. The sensation of lightning in the shimmer animation is caused by most of the placeholder content being darkened. The lightned part is not lightened: its only not darkened ! (using a gradient with a variying opacity). Make sure to understand that before choosing the best color for your app.
For android, i’m using <View /> tags with a background set to a plain color that i called placeholder (#d6d7dc).
For iOS, you may use UIView objects with a background. Or you can temporarily change the background and text colors of text items to the placeholder color: also add some fake text so text controls have a width.
If your app is using full linking in release mode on Android, add these lines to prevent the linker from optimizing away these methods:
[Preserve(AllMembers = true)]
public class ShimmerLinkerIncludeCore
public void FacebookShimmer()
_ = new ShimmerFrameLayout(null, null, 0, 0);
_ = new ShimmerFrameLayout(null, null, 0);
_ = new ShimmerFrameLayout(null, null);
All these files are available on this gist:
- ShimmeringTargetBinding.cs (Android)
- ShimmerExtensions.cs (iOS)
- home_common_shimmer.xml (Sample android Layout)