Gabic
Gabic

Reputation: 704

Create Android splash screen using SVG animation

I am developing an app using Xamarin.Forms and I am trying to insert the splash screen to my Android project.

I found a few tutorials for creating a splash screen with a background color and a static png image, but I want to use my svg animation as splash screen. I thought I could follow a tutorial for static image and just replace the png image with the svg animation, but it didn't work. Here's what I have so far:

On SplashActivity.cs:

[Activity(Label = "SplashActivity", Theme = "@style/Theme.Splash", MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Create your application here
        }

        protected override void OnResume()
        {
            base.OnResume();
            Task startupWork = new Task(() => { SimulateStartup(); });
            startupWork.Start();
        }

        async void SimulateStartup()
        {
            await Task.Delay(5000);
            StartActivity(new Intent(Application.Context, typeof(MainActivity)));
        }
    }

On MainActivity.cs:

// I only changed the MainLauncher property to false
[Activity(Label = "MyApp", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = false, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        ...
    }

On styles.xml (in the Xamarin.Android project):

<style name="Theme.Splash" parent="android:Theme">
    <item name="android:windowBackground">@drawable/desenhando5s</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="colorPrimaryDark">#004632</item>
  </style>

When I run the application, it only shows a black screen as splash screen and then shows my login page as always. Can anybody tell me what I have to do to set my animation as the splash screen?

(FYI: in case anyone wants to know, I created the animation using SVGator)

Upvotes: 1

Views: 1673

Answers (2)

user25030865
user25030865

Reputation:

To animate your Splash Icon and Splash Screen using android splash API You have to use animated-vector tag in your xml for 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:width="288dp"
        android:height="288dp"
        android:viewportWidth="288"
        android:viewportHeight="288">
        <group
            android:name="rotationGroup"
            android:pivotX="150"
            android:pivotY="150"
            android:scaleX="0.5"
            android:scaleY="0.5">
            <path
                android:fillColor="#535353"
                android:fillType="nonZero"
                android:pathData="M133,53.14L44.09,53.14L44.09,142.09L74.43,142.09L54.86,236.2L100.04,236.2L132.86,140.51C132.94,140.27 132.98,140.01 132.98,139.75ZM133,53.14"
                android:strokeColor="#00000000" />
            <path
                android:fillColor="#423C3C"
                android:fillType="nonZero"
                android:pathData="M94.52,125.35L71.46,236.2L54.86,236.2L74.43,142.09L44.09,142.09L44.09,53.14L61.5,53.14L61.5,123C61.5,123.63 61.75,124.22 62.18,124.66C62.63,125.1 63.22,125.35 63.84,125.35ZM94.52,125.35"
                android:strokeColor="#00000000" />
            <path
                android:fillColor="#535353"
                android:fillType="nonZero"
                android:pathData="M236.23,53.14L147.35,53.14L147.35,142.09L177.69,142.09L158.07,236.19L203.25,236.19L236.07,140.51C236.15,140.27 236.2,140.01 236.2,139.75ZM236.23,53.14"
                android:strokeColor="#00000000" />
            <path
                android:fillColor="#423C3C"
                android:fillType="nonZero"
                android:pathData="M197.76,125.35L174.7,236.2L158.07,236.2L177.65,142.1L147.35,142.1L147.35,53.14L164.76,53.14L164.76,123C164.76,123.63 165.01,124.22 165.45,124.66C165.89,125.1 166.48,125.35 167.11,125.35ZM197.76,125.35"
                android:strokeColor="#00000000" />
            <path
                android:fillColor="#00000000"
                android:pathData="M133,53.14L44.09,53.14L44.09,142.09L74.43,142.09L54.86,236.2L100.04,236.2L132.86,140.51C132.94,140.27 132.98,140.01 132.98,139.75ZM133,53.14"
                android:strokeWidth="5.69"
                android:strokeColor="#121331"
                android:strokeLineCap="round"
                android:strokeLineJoin="round" />
            <path
                android:fillColor="#00000000"
                android:pathData="M236.23,53.14L147.35,53.14L147.35,142.09L177.69,142.09L158.07,236.19L203.25,236.19L236.07,140.51C236.15,140.27 236.2,140.01 236.2,139.75ZM236.23,53.14"
                android:strokeWidth="5.69"
                android:strokeColor="#121331"
                android:strokeLineCap="round"
                android:strokeLineJoin="round" />
        </group>
    </vector>
</aapt:attr>

<target android:name="rotationGroup">
    <aapt:attr name="android:animation">
        <set>
            <objectAnimator
                android:duration="600"
                android:propertyName="rotation"
                android:repeatCount="1"
                android:repeatMode="reverse"
                android:valueFrom="0"
                android:valueTo="30"/>
        </set>
    </aapt:attr>
</target>
>

Make sure to replace the path data and other attributes with your specific values as needed.

Let me Explain this:

This is a tag animated-vector we are using for our drawable.

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">

You may notice that your icon image looks too large and extends beyond the splash icon size. To resolve this, you need to group your vector paths and then set the pivotX, pivotY, scaleX, and scaleY values.

 <<aapt:attr name="android:drawable">
    <vector
        android:width="288dp"
        android:height="288dp"
        android:viewportWidth="288"
        android:viewportHeight="288">
        <group
            android:name="rotationGroup"
            android:pivotX="150"
            android:pivotY="150"
            android:scaleX="0.5"
            android:scaleY="0.5">
            
            <path
                android:fillColor="#535353"
                android:fillType="nonZero"
                android:pathData="M133,53.14L44.09,53.14L44.09,142.09L74.43,142.09L54.86,236.2L100.04,236.2L132.86,140.51C132.94,140.27 132.98,140.01 132.98,139.75ZM133,53.14"
                android:strokeColor="#00000000" />
            <!-- Additional path data here -->
        </group>
    </vector>
</aapt:attr>>

Now that you have set up the splash icon, let me explain how to animate this SVG icon when the splash screen launches. For this, you need to use ObjectAnimator. Make sure to target the same group that you used to group your path data.

 <target android:name="rotationGroup">
    <aapt:attr name="android:animation">
        <set>
            <objectAnimator
                android:duration="600"
                android:propertyName="rotation"
                android:repeatCount="1"
                android:repeatMode="reverse"
                android:valueFrom="0"
                android:valueTo="30"/>
        </set>
    </aapt:attr>
</target>

First, initiate installSplashScreen() above setContentView. To animate the icon and splash screen, use .setKeepOnScreenCondition, and to animate the splash screen when it exits, use splashScreen.setOnExitAnimationListener:

class MainActivity : AppCompatActivity() {


@RequiresApi(Build.VERSION_CODES.S)
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    installSplashScreen()
    setContentView(R.layout.activity_on_boarding)

    //Handling Splash Screen Duration and animation
    var keepSplashOnScreen = true
    val delay = 2000L
    installSplashScreen().setKeepOnScreenCondition { keepSplashOnScreen }
    Handler(Looper.getMainLooper()).postDelayed({ keepSplashOnScreen = false }, delay)

    splashScreen.setOnExitAnimationListener { splashScreenView ->
        val slideLeft = ObjectAnimator.ofFloat(
            splashScreenView, View.TRANSLATION_X, 0f, -splashScreenView.height.toFloat()
        )
        slideLeft.interpolator = AnticipateInterpolator()
        slideLeft.duration = 500L
        slideLeft.doOnEnd { splashScreenView.remove() }
        slideLeft.start()
    }
}

}

Make sure to adjust the delay and slideLeft duration according to your requirements. You can also use other types of animations, such as slideUp, slideRight, etc.

Upvotes: 1

Wendy Zang - MSFT
Wendy Zang - MSFT

Reputation: 10978

You could use FFImageLoading to load your svg image in your SplashActivity instead of set it in styles.xml.

Splash screen:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FFImageLoading.Views.ImageViewAsync
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

Code:

protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Create your application here

        SetContentView(Resource.Layout.layout5);

        var filePath = "check";
        var imageView = FindViewById<ImageView>(Resource.Id.imageView);
        ImageService.Instance.LoadCompiledResource(filePath).WithCustomDataResolver(new SvgDataResolver(64, 0, true)).Into(imageView);
    }
    protected override void OnResume()
    {
        base.OnResume();
        Task startupWork = new Task(() => { SimulateStartup(); });
        startupWork.Start();
    }
    async void SimulateStartup()
    {
        await Task.Delay(5000);
        StartActivity(new Intent(Application.Context, typeof(MainActivity)));
    }

Updated:

Please check the screenshot. The .svg image is in the drawable folder. The layout5 is the splash screen in the layout folder.

enter image description here

Upvotes: 1

Related Questions