Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make my Xamarin.Forms for iOS and Android application show a splash screen as soon as possible after a user has opened the application?

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.

like image 597
Alan2 Avatar asked Aug 30 '18 23:08

Alan2


1 Answers

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.

like image 146
jamesfdearborn Avatar answered Oct 24 '22 16:10

jamesfdearborn