Navigation Architecture Component - Splash screen
You can try this, it currently works for me:
<action
android:id="@+id/action_splashFragment_to_profileFragment"
app:destination="@id/signInFragment"
app:launchSingleTop="true"
app:popUpTo="@id/splashFragment"
app:popUpToInclusive="true" />
Just set the popUpTo(the current destination)
and popUpToInclusive(true)
, this will pop all other screens until it gets to the specified destination - also pop the destination if popUpToInclusive()
is set to true
- before navigating to the new destination.
Splash screens have always been weird on Android. You only want to show a splash screen between clicking the app icon and the creation of the first Activity
. If your splash screen is a Fragment
the user will still see the white background until the first Activity
is created and the startup time of your app will increase because a splash Fragment
has to be created and removed. The best practice is to use a splash AppTheme
like Ian Lake (an Android Framework Engineer) explains in this post.
As for navigation, your app should have a fixed destination which is the first and last screen a user sees when entering and exiting your app like explained in the principles of navigation. In your case it would make sense to make the ChatFragment
the fixed destination. In the onCreate
of the ChatFragment
you should check if the user already has a profile and redirect them to the ProfileFragment
using conditional navigation if they don't.
There is a common misuse of the splash screen when it is shown to the user for some amount of seconds, and users are wasting their time looking at the Splash screen while they could already interact with the App. Instead of that, you should get them ASAP to the screen where they could interact with the App. Because of that previously Splash screen was considered anti-pattern on android. But then Google realized that there still exist short window between user had clicked on the icon and your first App screen is ready for interaction, and during that time you can show some branding information. This is the right way to implement a Splash screen.
So to implement Splash screen the right way you don't need separate Splash Fragment as it will introduce an unnecessary delay in App loading. To do it you will need only special theme. In theory App theme could be applied to UI and becomes visible much sooner than your App UI will be initialized and become visible. So in a nutshell, you just need SplashTheme
like this:
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash_background</item>
</style>
splash_background
drawable should be like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque"> <!-- android:opacity="opaque" should be here -->
<item>
<!--this is your background, you can use color, gradient etc.-->
<color android:color="@color/colorPrimary"/>
<!--<shape>
<gradient
android:angle="315"
android:endColor="#1a82ff"
android:startColor="#2100d3"
android:type="linear"/>
</shape> -->
</item>
<item>
<bitmap android:src="@drawable/ic_logo"
android:gravity="center"/>
</item>
</layer-list>
Your fragments will be anyway hosted in some activity, let's call it MainActivty
. In the Manifest
just add SplashTheme
to your Activity (that will show the splash screen theme from the moment user had clicked the App icon) :
<activity android:name=".ui.MainActivity"
android:theme="@style/SplashTheme">
Then in MainActivity
to return to your regular AppTheme
do this in onCreate
before super
call :
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
.....