9
votes

I'm looking for hints, an example or anything that could guide me with how to make a start up splash screen for Xamarin application Xamarin.Forms application.

I assume I need to make different changes to the iOS and the Android projects and have researched what I can find already.

However much of the information seems dated or no longer works.

Would appreciate any suggestions and advice on how to do this for iOS and Android.

2
There's some tutorials out there that show this. This is one of the more recently made ones I've found. Here's another one from Adam Pedley, a Microsoft MVP, but I think the iOS part is a little dated.Andrew
I tried both of these links but neither seem to help with iOS. One is not for forms and the other is as you mention not up to date.Alan2
Do you want to open app very fast, w/o taking much time on splash screen?R15
@Arvindraja - I would like it to open as fast as possible and show a simple splash screen before it opens. I am expecting I would have to implement some different code for iOS and Android in their projects and maybe there's a change I need to make to the shared code. Hope for some good suggestions.Alan2

2 Answers

11
votes

Xamarin.Forms is a solution that, in itself, takes a while to load. Since all cross-platform things have to wait for Xamarin, there is no cross-platform good implementation of a splash screen.

It looks like you'll have to implement it separately for iOS and Android. This will enable the splash screen to show up much faster and before the standard blue Xamarin screen.

EDIT: Alan asked for a complete solution, so here it is:

iOS: Make changes to the LaunchScreen.storyboard file in the Resources section of the .iOS project (that's the splash screen, by the way). I'd suggest opening it in Xcode instead because the storyboard editor of Xcode is frankly just better than Xamarin.

Android: You're going to have to have an image here. From official Xamarin support-

The quickest way to render and display the splash screen is to create a custom theme and apply it to an Activity that exhibits the splash screen. When the Activity is rendered, it loads the theme and applies the drawable resource (referenced by the theme) to the background of the activity. This approach avoids the need for creating a layout file. The splash screen is implemented as an Activity that displays the branded drawable, performs any initializations, and starts up any tasks. Once the app has bootstrapped, the splash screen Activity starts the main Activity and removes itself from the application back stack.

Here's the specific code involved for that. Below is for a drawable. Place it in the Resources/Drawable folder of the Android project.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <color android:color="@color/splash_background"/>
  </item>
  <item>
    <bitmap
        android:src="@drawable/splash"
        android:tileMode="disabled"
        android:gravity="center"/>
  </item>
</layer-list>

This is for a theme (add it to values/styles.xml, or add values/styles.xml if the document doesn't exist.).

<resources>
  <style name="MyTheme.Base" parent="Theme.AppCompat.Light">
  </style>

  <style name="MyTheme" parent="MyTheme.Base">
  </style>

  <style name="MyTheme.Splash" parent ="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_screen</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
  </style>
</resources>

Add this code to your Android project as MyTheme.cs:

[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : AppCompatActivity
{
    static readonly string TAG = "X:" + typeof(SplashActivity).Name;

    public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
    {
        base.OnCreate(savedInstanceState, persistentState);
        Log.Debug(TAG, "SplashActivity.OnCreate");
    }

    // Launches the startup task
    protected override void OnResume()
    {
        base.OnResume();
        Task startupWork = new Task(() => { SimulateStartup(); });
        startupWork.Start();
    }

    // Simulates background work that happens behind the splash screen
    async void SimulateStartup ()
    {
        Log.Debug(TAG, "Performing some startup work that takes a bit of time.");
        await Task.Delay (8000); // Simulate a bit of startup work.
        Log.Debug(TAG, "Startup work is finished - starting MainActivity.");
        StartActivity(new Intent(Application.Context, typeof (MainActivity)));
    }
}

Then, after you've done all that for Android, remove the MainLauncher attribute from MainActivity, since your launcher is now MyTheme.

This is by no means easy, but it's the only way there is right now.

-2
votes

Make sure you do not have SimulateStartup sample code. It used to be boiler plate code a while ago:

class SplashActivity:

It forces an await when the app starts up incase you want to make any service calls on the splash screen

MainActivity.cs

// Launches the startup task
protected override void OnResume()
{
    base.OnResume();
    Task startupWork = new Task(() => { SimulateStartup(); });
    startupWork.Start();
}

// Simulates background work that happens behind the splash screen
async void SimulateStartup ()
{
    Log.Debug(TAG, "Performing some startup work that takes a bit of time.");
    await Task.Delay (8000); // Simulate a bit of startup work.
    Log.Debug(TAG, "Startup work is finished - starting MainActivity.");
    StartActivity(new Intent(Application.Context, typeof (MainActivity)));
}

Other alternative to improve splash speed:

  • use small or native components to create your splash screen
  • make sure nothing is on OnResume and not calling any services