Detecting First Time App Launch In Flutter

Programmers Pouch
5 min readNov 11, 2021

--

Showing the same splash screen again and again after user launches app is boringšŸ„±. You mightā€™ve seen in most of the apps that at the appā€™s first time launch, the splash is different than the second time launch. Thatā€™s what we are going to implement in this articlešŸ˜®.

This is what we are going to make.

First Time(Left) and Thereafter(Right)

If you havenā€™t yet read my article of how to implement a normal splash screen, then you can check it out right here.

Weā€™ll be using the package called shared_preferences for this thing to come true and another package called sleek_circular_slider which is a highly customizable circular slider/progress bar & spinner for Flutter.

So add both of them to the pubspec.yaml to their latest versions:

dependencies:
shared_preferences: ^2.0.6
sleek_circular_slider: ^2.0.1

Now, letā€™s go one with the code.

Create a new dart file named shared_preferences that will hold the logic. In that file make a stful widget naming it SharedPref. To detect the first time launch, letā€™s create a boolean value for it too.

class SharedPref extends StatefulWidget {
const SharedPref({Key key}) : super(key: key);

@override
_SharedPrefState createState() => _SharedPrefState();
}

class _SharedPrefState extends State<SharedPref> {
bool isFirstLaunch = false;

@override
Widget build(BuildContext context) {
return Scaffold();
}
}

Now initialize the boolean value with the SharedPreferences package.

bool isFirstLaunch = false;

SharedState() {
MySharedPreferences.instance
.getBooleanValue("isfirstRun")
.then((value) => setState(() {
isFirstLaunch = value;
}));
}

Now to show the respective splash screens.

Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Launch Detection Demo',
//if true return intro screen for first time Else go to login Screen
home: isFirstLaunch ? FirstSplashScreen() : SecondSplashScreen());
}

Make a class outside of the stful widget thatā€™ll help us with the logic

class MySharedPreferences {
MySharedPreferences._privateConstructor();

static final MySharedPreferences instance =
MySharedPreferences._privateConstructor();

setBooleanValue(String key, bool value) async {
SharedPreferences myPrefs = await SharedPreferences.getInstance();
myPrefs.setBool(key, value);
}

Future<bool> getBooleanValue(String key) async {
SharedPreferences myPrefs = await SharedPreferences.getInstance();
return myPrefs.getBool(key) ?? false;
}
}

We are done with the logic. Now letā€™s move onto the other screens

This splash screen, the FirstSplashScreen is meant only for the first time launch. Letā€™s make it.

Create new dart file named first_splash_screen and make a stful widget named FirstSplashScreen and the other respective variables. [Donā€™t forget to import dart:async]

class FirstSplashScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() => StartState();
}

class StartState extends State<FirstSplashScreen> {
@override
Widget build(BuildContext context) {
return initScreen(context);
}

@override
void initState() {
super.initState();
startTimer();
}

startTimer() async {
var duration = Duration(seconds: 17);
return new Timer(duration, route);
}

route() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomeScreen()));
}

Letā€™s go on with the simple UI.

initScreen(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueAccent,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Launch Detection Demo',
style: TextStyle(fontSize: 50.0, color: Colors.white),
),
SizedBox(
height: 20,
),
SleekCircularSlider(
min: 0,
max: 100,
initialValue: 100,
appearance: CircularSliderAppearance(
infoProperties: InfoProperties(
mainLabelStyle: TextStyle(
color: Colors.white,
fontSize: 25,
)),
customColors: CustomSliderColors(
dotColor: Colors.white,
progressBarColor: Colors.black,
shadowColor: Colors.white,
trackColor: Colors.white),
spinnerDuration: 10,
animDurationMultiplier: 10,
animationEnabled: true,
startAngle: 0.0,
angleRange: 360,
),
),
Text(
'Initializing app...',
style: TextStyle(color: Colors.white, fontSize: 20),
),
],
),
),
);
}

We are done with this screen too. Letā€™s complete the other one now.

This splash screen, the SecondSplashScreen is meant only for the second time launch and thereafter.

Make a new dart file named second_splash_screen and make a stful widget called SecondSplashScreen and the other respective variables. [Donā€™t forget to import dart:async]

class SecondSplashScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() => StartState();
}

class StartState extends State<SecondSplashScreen> {
@override
Widget build(BuildContext context) {
return initScreen(context);
}

@override
void initState() {
super.initState();
startTimer();
}

startTimer() async {
var duration = Duration(seconds: 5);
return new Timer(duration, route);
}

route() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),
),
);
}

Letā€™s go on with the simple UI now.

initScreen(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueAccent,
body: Padding(
padding: EdgeInsets.only(top: 20.0, left: 20.0, right: 20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Center(
child: Text(
'Launch Detection Demo',
style: TextStyle(fontSize: 50.0, color: Colors.white),
),
),
SizedBox(
height: 20,
),
SleekCircularSlider(
appearance: CircularSliderAppearance(
customColors: CustomSliderColors(
dotColor: Colors.white,
progressBarColor: Colors.black,
shadowColor: Colors.white,
trackColor: Colors.white),
spinnerMode: true,
animationEnabled: true,
size: 50.0,
customWidths:
CustomSliderWidths(trackWidth: 10.0, shadowWidth: 5.0),
),
initialValue: 90,
onChange: (double value) {
print(value);
},
),
],
),
),
);
}

We are done with this screen as well.

Now letā€™s create the home screen for just the sake of making it.

import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
const HomeScreen({Key key}) : super(key: key);

@override
_HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueAccent,
body: Center(child: Text('Good Luck For Your Awesome Flutter Journey', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),)),
);
}
}

Your main.dart will look something like this:

import 'package:flutter/material.dart';
import 'shared_preferences.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SharedPref(),
);
}
}

Andā€¦. thatā€™s itšŸ

If you liked the article, make sure to smash that clap buttonšŸ‘. Donā€™t forget to follow me for many other articles like that.

Buy me a coffeeā˜• to show me your support.

Reach me out at GitHub here. You can find the source here.

Later!šŸ‘‹

--

--