Android Splashscreen

How do I make a splash screen?

Further reading:

  • App Launch time & Themed launch screens (Android Performance Patterns Season 6 Ep. 4)
  • Splash screen in Android: The right way

Old answer:

HOW TO: Simple splash screen

This answers shows you how to display a splash screen for a fixed amount of time when your app starts for e.g. branding reasons. E.g. you might choose to show the splash screen for 3 seconds. However if you want to show the spash screen for a variable amount of time (e.g. app startup time) you should check out Abdullah's answer https://stackoverflow.com/a/15832037/401025. However be aware that app startup might be very fast on new devices so the user will just see a flash which is bad UX.

First you need to define the spash screen in your layout.xml file

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<ImageView android:id="@+id/splashscreen" android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/splash"
android:layout_gravity="center"/>

<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, splash"/>

</LinearLayout>

And your activity:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

public class Splash extends Activity {

/** Duration of wait **/
private final int SPLASH_DISPLAY_LENGTH = 1000;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splashscreen);

/* New Handler to start the Menu-Activity
* and close this Splash-Screen after some seconds.*/
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(Splash.this,Menu.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
}, SPLASH_DISPLAY_LENGTH);
}
}

Thats all ;)

Android 12 Splash Screen API - Increasing SplashScreen Duration

As I was writing this question and almost ready to post it, I stumbled on the method setKeepOnScreenCondition (below) that belongs to the splashScreen that we must install on the onCreate of our main activity. I thought it seemed wasteful not to post this, given there are no other posts on this topic and no such similar answers to other related questions (as of Jan 2022).

SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
plashScreen.setKeepOnScreenCondition(....);

Upon inspecting it I found this method receives an instance of the splashScreen.KeepOnScreenCondition() interface for which the implementation must supply the following method signature implementation:

 public boolean shouldKeepOnScreen() 

It seems this method will be called by the splash screen and retain the splash screen visibly until it returns false. This is where the light bulb moment I so love about programming occurred.

What if I use a boolean initialized as true, and set it to false after a delay? That hunch turned out to work. Here is my solution. It seems to work and I thought it would be useful to others. Presumably instead of using a Handler for a delay, one could also use this to set the boolean after some process had completed.

package com.example.mystuff.myactivity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.splashscreen.SplashScreen;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends AppCompatActivity {

private boolean keep = true;
private final int DELAY = 1250;

@Override
protected void onCreate(Bundle savedInstanceState) {
// Handle the splash screen transition.
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
super.onCreate(savedInstanceState);

//Keep returning false to Should Keep On Screen until ready to begin.
splashScreen.setKeepOnScreenCondition(new SplashScreen.KeepOnScreenCondition() {
@Override
public boolean shouldKeepOnScreen() {
return keep;
}
});
Handler handler = new Handler();
handler.postDelayed(runner, DELAY);
}

/**Will cause a second process to run on the main thread**/
private final Runnable runner = new Runnable() {
@Override
public void run() {
keep = false;
}
};

}

If you are into Java Lambdas an even nicer and more compact solution is as follows:

package com.example.mystuff.myactivity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.splashscreen.SplashScreen;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends AppCompatActivity {

private boolean keep = true;
private final int DELAY = 1250;

@Override
protected void onCreate(Bundle savedInstanceState) {
// Handle the splash screen transition.
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//Keep returning false to Should Keep On Screen until ready to begin.
splashScreen.setKeepOnScreenCondition(() -> keep);
Handler handler = new Handler();
handler.postDelayed(() -> keep = false, DELAY);;
}



}

If you have comments or feedback (besides telling me I should not increase the duration of the splash screen), or a better way please do comment or respond with additional answers.

New Splash screen is shown cut in a cyrcle shape

What you can do is to wrap your icon in an inset drawable so that it is drawn inside the circle.

For example, create a drawable/splash_inset.xml resource:

<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_visual_vector"
android:insetLeft="72dp"
android:insetRight="72dp"
android:insetTop="72dp"
android:insetBottom="72dp"/>

The actual inset values depend on your image and its aspect ratio, using 72dp here on all edges as an example.

Then apply this drawable as your windowSplashScreenAnimatedIcon.



Related Topics



Leave a reply



Submit