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.