DEV Community

Luis Beltran
Luis Beltran

Posted on

Animated Splash Screen in .NET MAUI Android

This article is part of the #MAUIUIJuly initiative by Matt Goldman. You'll find other helpful articles and tutorials published daily by community members and experts there, so make sure to check it out every day.

Beginning with Android 12, the Splash Screen API allows you to define an animated splash screen that plays when the app starts (without having to set up a custom Activity with a gif or an animation, as some people would not consider it a true splash screen). This API also allows you to:

  • customize the icon background color
  • customize the window background color
  • set up a transition to the app after the splash screen plays

Before I explain how to do it in a .NET MAUI app, let's be clear about some important things:

  • An animated splash screen in Android is defined as an Animated Vector Drawable.

  • Currently, Launch Screens on iOS can't be animated unless you apply some tricks (in general, you can do the same in a .NET MAUI app, simply set the MainPage in App.xaml.cs to any ContentPage which starts immediately after the static Splash Screen plays and that contains some sort of animation, such as a .gif, a Lottie animation or of course, Animations). Then, after the animation ends, navigate to your true Home Page. However, some people might argue that that's not really a Splash Screen, although it does the job of playing an animation before the user is finally able to interact with the application :)

  • Disclaimer: this is not really a new topic. Several blog posts on Internet already talk about the Splash Screen Android API in a .NET MAUI app to customize the window and icon background color, for example. However, I only found one -in German language- which implements the animated splash screen. By the way, here is another blog post that explains how to do the same for our old good pal Xamarin.

Anyways, let's code!

Step 1. Add a NuGet package

Add the Xamarin.AndroidX.Core.SplashScreen NuGet package to your .NET MAUI project.

Image description

Step 2. Add an AVD as an AndroidResource

Add the Animated Vector Drawable where you define your animation. You can use tools such as ShapeShifter to create them from SVG files. There is also an interesting CLI tool that converts Lottie Json Animations to Android Animated Vector Drawable XML

  • You might need to create a drawable folder under Platforms/Android/Resources.
  • Set the Build Action of the file to AndroidResource.

Image description

Sample Animated Vector Drawable:

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">
        <vector
            android:name="vector"
            android:width="32dp"
            android:height="32dp"
            android:viewportWidth="32"
            android:viewportHeight="32">
            <group android:name="group">
                <path
                    android:name="path_end"
                    android:pathData="M 15.12 15.53 L 25 5.66 C 25.191 5.496 25.437 5.411 25.689 5.42 C 25.941 5.43 26.18 5.534 26.358 5.712 C 26.536 5.89 26.64 6.129 26.65 6.381 C 26.659 6.633 26.574 6.879 26.41 7.07 L 17.35 16.13 L 26.15 24.93 C 26.336 25.117 26.441 25.371 26.441 25.635 C 26.441 25.899 26.336 26.153 26.15 26.34 C 26.026 26.465 25.871 26.555 25.7 26.601 C 25.53 26.647 25.35 26.647 25.18 26.601 C 25.009 26.555 24.854 26.465 24.73 26.34 L 15.12 16.73 C 14.961 16.571 14.872 16.355 14.872 16.13 C 14.872 15.905 14.961 15.689 15.12 15.53 Z"
                    android:fillColor="#00446a"
                    android:fillAlpha="0"
                    android:strokeWidth="1"/>
                <path
                    android:name="path_start"
                    android:pathData="M 5.54 15.53 L 15.42 5.66 C 15.564 5.492 15.76 5.376 15.978 5.331 C 16.195 5.286 16.421 5.315 16.62 5.413 C 16.819 5.51 16.98 5.671 17.077 5.87 C 17.175 6.069 17.204 6.295 17.159 6.512 C 17.114 6.73 16.998 6.926 16.83 7.07 L 7.77 16.13 L 16.57 24.93 C 16.756 25.117 16.861 25.371 16.861 25.635 C 16.861 25.899 16.756 26.153 16.57 26.34 C 16.383 26.526 16.129 26.631 15.865 26.631 C 15.601 26.631 15.347 26.526 15.16 26.34 L 5.54 16.73 C 5.381 16.571 5.292 16.355 5.292 16.13 C 5.292 15.905 5.381 15.689 5.54 15.53 Z"
                    android:fillColor="#00446a"
                    android:fillAlpha="0"
                    android:strokeWidth="1"/>
            </group>
        </vector>
    </aapt:attr>
    <target android:name="path_start">
        <aapt:attr name="android:animation">
            <set>
                <objectAnimator
                    android:propertyName="fillAlpha"
                    android:startOffset="500"
                    android:duration="500"
                    android:valueFrom="0"
                    android:valueTo="1"
                    android:valueType="floatType"
                    android:interpolator="@android:anim/linear_interpolator"/>
                <objectAnimator
                    android:propertyName="fillColor"
                    android:startOffset="1000"
                    android:duration="500"
                    android:valueFrom="#00446a"
                    android:valueTo="#ff2266"
                    android:valueType="colorType"
                    android:interpolator="@android:interpolator/fast_out_slow_in"/>
                <objectAnimator
                    android:propertyName="fillAlpha"
                    android:startOffset="2000"
                    android:duration="500"
                    android:valueFrom="1"
                    android:valueTo="0.5"
                    android:valueType="floatType"
                    android:interpolator="@android:anim/linear_interpolator"/>
                <objectAnimator
                    android:propertyName="fillAlpha"
                    android:startOffset="2500"
                    android:duration="500"
                    android:valueFrom="0.5"
                    android:valueTo="1"
                    android:valueType="floatType"
                    android:interpolator="@android:anim/linear_interpolator"/>
            </set>
        </aapt:attr>
    </target>
    <target android:name="path_end">
        <aapt:attr name="android:animation">
            <set>
                <objectAnimator
                    android:propertyName="fillAlpha"
                    android:startOffset="300"
                    android:duration="800"
                    android:valueFrom="0"
                    android:valueTo="1"
                    android:valueType="floatType"
                    android:interpolator="@android:anim/linear_interpolator"/>
                <objectAnimator
                    android:propertyName="fillAlpha"
                    android:startOffset="1100"
                    android:duration="800"
                    android:valueFrom="1"
                    android:valueTo="0.5"
                    android:valueType="floatType"
                    android:interpolator="@android:anim/linear_interpolator"/>
                <objectAnimator
                    android:propertyName="fillAlpha"
                    android:startOffset="1900"
                    android:duration="600"
                    android:valueFrom="0.5"
                    android:valueTo="1"
                    android:valueType="floatType"
                    android:interpolator="@android:anim/linear_interpolator"/>
            </set>
        </aapt:attr>
    </target>
</animated-vector>
Enter fullscreen mode Exit fullscreen mode

Step 3. Define a Theme

Next up, add a themes.xml file under Platforms/Android/Resources/values. Set its Build Action to AndroidResource as well.

Image description

In this file you configure a style:

  • You must set a name for your theme (style) because it will be referenced later in MainActivity.cs.
  • The theme must inherit from Theme.SplashScreen (use the parent property for that).
  • You must set the element in the animated splash screen using the windowSplashScreenAnimatedIcon attribute in an item element.
  • You must set the windowSplashScreenAnimationDuration value only if your app targets Android 12. Otherwise, the value is optional and is obtained from the Animated Vector Drawable itself.
  • The windowSplashScreenBackground that defines the background color for the starting window is optional.
  • According to this reference, you must also set the postSplashScreenTheme property to the theme that the Activity will use after the Splash Screen dissapears.

Sample code for themes.xml:

<resources>
    <style name="Theme.Animated" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@android:color/white</item>
        <item name="windowSplashScreenAnimatedIcon">@drawable/cloud</item>
        <item name="windowSplashScreenAnimationDuration">1300</item>
        <item name="postSplashScreenTheme">@style/Maui.MainTheme.NoActionBar</item>
    </style>
</resources>
Enter fullscreen mode Exit fullscreen mode

Step 4. Call InstallSplashScreen in MainActivity before calling base.onCreate().

  • In MainActivity.cs, override its onCreate method and invoke the InstallSplashScreen static function before base.onCreate().

  • The class AndroidX.Core.SplashScreen.SplashScreen is required and it can be imported with the static modifier.

  • And don't forget to set the value for Theme in the Activity attribute. Simply set it to the name that you previously defined in your style (in themes.xml):

Code for MainActivity.cs:

using Android.App;
using Android.Content.PM;
using Android.OS;

using static AndroidX.Core.SplashScreen.SplashScreen;

namespace AnimatedSplashScreenApp
{
    [Activity(Theme = "@style/Theme.Animated", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
    public class MainActivity : MauiAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            var splash = InstallSplashScreen(this);
            base.OnCreate(savedInstanceState);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 5. (Clean, Re)Build & Test your App

Now you can build and test your app. This is the outcome:

Image description

In case you edit the animation and can't see the latest version of it, simply Clean and Rebuild the project.

As you can see, it is very easy to add an animated splash screen in Android using .NET MAUI. Perhaps the hardest part is to play with the svg and create an animation from it. You can get some inspiration from these animated vector drawables or learn more about the Shape Shifter tool with a tutorial.

By the way, you can do even more things. As explained here -in German language-:

  • There can be situations in which you want to extend the animation display time because you would like to do some work in the background, such as loading app settings or data before the first view is displayed. To do this, you can register a listener with the ViewTreeObserver and define a OnPreDraw function from the IOnPreDrawListener interface on MainActivity.

  • By implementing the IOnExitAnimationListener interface, you can set the exit animation, such as a slide-up that looks pretty neat.

  • You can also add a branding image in your Splash Screen by defining it in the style (themes.xml). Use the windowSplashScreenBrandingImage property for that.

The source code of this blog post can be found here.

I hope that this post was interesting and useful for you. Thanks for your time, and enjoy the rest of the #MAUIUIJuly publications!

Other references

  1. Let's customize the Splash Screen of a MAUI app
  2. Sketch + Animated Vector Drawable = ❤️
  3. An Introduction to Icon Animation Techniques

Top comments (1)

Collapse
 
phantomkna profile image
Phantom_KNA

Thanks for sharing