Search code examples
c#xmlxamarin.androidmonogame

My splash screen ends too early. How can I manually hide a splash screen on Android?


I have created a splash screen theme for my Android game. But the problem is that my splash screen automatically ends after OnCreate(Bundle bundle) was fully executed and this results in a black screen before Draw(GameTime gameTime) is executed. I draw my game's sprites in Draw(GameTime gameTime). Therefore, there is a black screen until Draw(GameTime gameTime) is executed.

Is it possible to manually end the splash screen when my game code has already reached Draw(GameTime gameTime)? I don't want that the splash screen already ends when OnCreate(Bundle bundle) was fully executed.

splash_screen_svg.xml:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="320dp"
android:height="480dp"
android:viewportWidth="84.666664"
android:viewportHeight="127">
<path
  android:pathData="M0.529,0.529h83.608v125.942h-83.608z"
  android:strokeWidth="1.05833"
  android:fillColor="#00ffff"
  android:strokeColor="#000000"/>
<path
  android:pathData="M21.431,32.015h41.804v62.971h-41.804z"
  android:strokeWidth="0.529167"
  android:fillColor="#ff0000"
  android:strokeColor="#000000"/>
</vector>

colors.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<resources>
  <color name="splash_background">#eff1f7</color>
</resources>

Strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="app_name">splashapp</string>
</resources>

styles.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<resources>
 <style name="MainTheme" parent="MainTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
    <!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
    <item name="android:windowNoTitle">true</item>
    <!--We will be using the toolbar so no need to show ActionBar-->
    <item name="android:windowActionBar">false</item>
     <item name="android:windowFullscreen">true</item>
    <!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette -->
    <!-- colorPrimary is used for the default action bar background -->
    <item name="android:colorPrimary">#2196F3</item>
    <!-- colorPrimaryDark is used for the status bar -->
    <item name="android:colorPrimaryDark">#1976D2</item>
    <!-- colorAccent is used as the default value for colorControlActivated
     which is used to tint widgets -->
    <item name="android:colorAccent">#FF4081</item>
    <!-- You can also set colorControlNormal, colorControlActivated
     colorControlHighlight and colorSwitchThumbNormal. -->
    <item name="android:windowActionModeOverlay">true</item>
    <item name="android:windowIsTranslucent">true</item>
</style>
<style name="SplashTheme" parent ="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@drawable/splash_screen_svg</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
</resources>

Activity1.cs:

namespace splashapp
{
[Activity(
    Label = "@string/app_name",
    MainLauncher = true,
    Theme = "@style/SplashTheme",
    Icon = "@drawable/icon",
    AlwaysRetainTaskState = true,
    LaunchMode = LaunchMode.SingleInstance,
    ScreenOrientation = ScreenOrientation.FullUser,
    ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize
)]
public class Activity1 : AndroidGameActivity
{
    private Game1 _game;
    private View _view;

    protected override void OnCreate(Bundle bundle)
    {
        base.SetTheme(Resource.Style.MainTheme);
        base.OnCreate(bundle);
        _game = new Game1();
        _view = _game.Services.GetService(typeof(View)) as View;
        SetContentView(_view);
        _game.Run();
    }
}
}

Game1.cs:

namespace splashapp
{
public class Game1 : Game
{
    private GraphicsDeviceManager _graphics;
    private SpriteBatch _spriteBatch;

    public Game1()
    {
        _graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        base.Initialize();
    }

    protected override void LoadContent()
    {
        _spriteBatch = new SpriteBatch(GraphicsDevice);
        
        // TODO: use this.Content to load your game content here
    }

    protected override void Update(GameTime gameTime)
    {
        // TODO: Add your update logic here

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        // TODO: Add your drawing code here

        base.Draw(gameTime);
    }
}
}

My solution picture


Solution

  • Is it possible to use my splash_screen_svg.xml or a svg file for it?

    Create a splash_screen.xml in drawable folder.

    <?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_logo"
        android:tileMode="disabled"
        android:gravity="center"/>
      </item>
    </layer-list>
    

    Add specifial color in Resources/values/colors.xml.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
      ...
      <color name="splash_background">#FFFFFF</color>
    </resources>
    

    Create a Theme in Resources/values/styles.xml

     <style name="Theme_SplashScreen" 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>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowActionBar">true</item>
    

    Load the splash screen in Activity_SplashScreen activity.

     [Activity(Label = "Activity_SplashScreen", Theme = "@style/Theme_SplashScreen", MainLauncher = true)]
    public class Activity_SplashScreen : 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();
        }
        // Simulates background work that happens behind the splash screen
        async void SimulateStartup()
        {             
            await Task.Delay(3000); // Simulate a bit of startup work.            
            StartActivity(new Intent(Application.Context, typeof(Activity_Screen)));
        }
    }
    

    Activity_Screen activity:

     [Activity(Label = "Activity_Screen")]
    public class Activity_Screen : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
    
            // Create your application here
            SetContentView(Resource.Layout.layout_Screen);
            Toast.MakeText(this, "Welcome to MainActivity", ToastLength.Long).Show();
        }
    }