Reputation: 21
I wanna make my onboarding screen shown only once when installing an application in the device
> import 'package:flutter/foundation.dart';
> import 'package:flutter/material.dart';
> import 'package:flutter/services.dart';
> import 'package:introduction_screen/introduction_screen.dart';
>
> import 'widget_tree.dart';
>
> class IntroScreen extends StatefulWidget {
> @override
> _IntroScreenState createState() => _IntroScreenState();
> }
>
> class _IntroScreenState extends State<IntroScreen> {
> final introKey = GlobalKey<IntroductionScreenState>();
> late final bool isFirstRun;
> get child => null;
>
> void _onIntroEnd(context) {
> Navigator.of(context).push(
> MaterialPageRoute(builder: (_) => WidgetTree()),
> );
> }
>
> Widget _buildFullscreenImage() {
> return Image.asset(
> 'assets/images/intro1.png',
> fit: BoxFit.cover,
> height: double.infinity,
> width: double.infinity,
> alignment: Alignment.center,
> );
> }
>
> Widget _buildImage(String assetName, [double width = 350]) {
> return Image.asset('assets/$assetName', width: width);
> }
>
> @override
> Widget build(BuildContext context) {
> const bodyStyle = TextStyle(fontSize: 19.0);
>
> const pageDecoration = PageDecoration(
> titleTextStyle: TextStyle(
> color: Color.fromARGB(255, 29, 116, 182),
> fontSize: 30.0,
> fontWeight: FontWeight.w700,
> fontFamily: 'assets/fonts/Ubuntu-B.ttf'),
> bodyTextStyle: bodyStyle,
> bodyPadding: EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0),
> pageColor: Color.fromARGB(0, 255, 255, 255),
> imagePadding: EdgeInsets.zero,
> );
>
> return IntroductionScreen(
> key: introKey,
> globalBackgroundColor: Colors.white,
> globalHeader: const Align(
> alignment: Alignment.topRight,
> child: SafeArea(
> child: Padding(
> padding: EdgeInsets.only(top: 16, right: 16),
> // child: _buildImage('flutter.png', 100),
> ),
> ),
> ),
> /*globalFooter: SizedBox(
> width: double.infinity,
> height: 60,
> child: ElevatedButton(
> style:const ButtonStyle(alignment:Alignment(1, 1)),
> child: const Text(
> 'Skip!',
> style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
> ),
> onPressed: () => _onIntroEnd(context),
> ),
> ),*/
>
> pages: [
> PageViewModel(
> title: ('WELCOME'),
> body:
> 'To the Mawed , which allows you to book a clinic easily . Choose the hospital that suits you and the doctor you want.',
> image: Image.asset(
> 'assets/images/intro1.png',
> width: 400,
> height: 400,
> fit: BoxFit.fitWidth,
> alignment: AlignmentDirectional.bottomCenter,
> ),
> decoration: pageDecoration,
> ),
> PageViewModel(
> title: "Book Now",
> body: " From your home easly & Keep the ticket to show when asked",
> image: Image.asset(
> 'assets/images/intro2.jpg',
> width: 350,
> height: 350,
> fit: BoxFit.fitWidth,
> alignment: AlignmentDirectional.center,
> ),
> decoration: pageDecoration,
> ),
> PageViewModel(
> title: "Avoid",
> body: "Crowding and wasting time, and go on time.",
> image: Image.asset(
> 'assets/images/intro3.jpg',
> width: 350,
> height: 350,
> fit: BoxFit.fitWidth,
> alignment: AlignmentDirectional.center,
> ),
> decoration: pageDecoration,
> ),
> PageViewModel(
> title: "Choose the hospital",
> body: "That suits & the closest to you",
> image: Image.asset(
> 'assets/images/intro4.jpg',
> width: 350,
> height: 350,
> fit: BoxFit.fitWidth,
> alignment: AlignmentDirectional.center,
> ),
> decoration: pageDecoration,
> ),
> PageViewModel(
> title: "What do you feel ?",
> body: "Choose the clinic or medical specialty carefully",
> image: Image.asset('assets/images/intro5.png',
> width: 350,
> height: 350,
> fit: BoxFit.fitWidth,
> alignment: AlignmentDirectional.center),
> decoration: pageDecoration,
> ),
> PageViewModel(
> title: "Get to know ",
> body: "Your doctor's appointments and choose the time you want.",
> image: Image.asset('assets/images/intro6.png',
> width: 400,
> height: 400,
> fit: BoxFit.fitWidth,
> alignment: AlignmentDirectional.bottomCenter),
> decoration: pageDecoration,
> ),
> ],
> onDone: () => _onIntroEnd(context),
> onSkip: () => _onIntroEnd(context), // You can override onSkip callback
> showSkipButton: false,
> skipOrBackFlex: 0,
> nextFlex: 0,
> showBackButton: true,
> //rtl: true, // Display as right-to-left
> back: const Icon(Icons.arrow_back),
> skip: const Text('Skip', style: TextStyle(fontWeight: FontWeight.w600)),
> next: const Icon(Icons.arrow_forward),
> done:
> const Text('Book Now', style: TextStyle(fontWeight: FontWeight.w600)),
> curve: Curves.fastLinearToSlowEaseIn,
> controlsMargin: const EdgeInsets.all(16),
> controlsPadding: kIsWeb
> ? const EdgeInsets.all(12.0)
> : const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 4.0),
> dotsDecorator: const DotsDecorator(
> size: Size(10.0, 10.0),
> color: Color(0xFFBDBDBD),
> activeSize: Size(22.0, 10.0),
> activeShape: RoundedRectangleBorder(
> borderRadius: BorderRadius.all(Radius.circular(25.0)),
> ),
> ),
> dotsContainerDecorator: const ShapeDecoration(
> color: Colors.black87,
> shape: RoundedRectangleBorder(
> borderRadius: BorderRadius.all(Radius.circular(8.0)),
> ),
> ),
> );
> }
> }
>
Upvotes: 2
Views: 1829
Reputation: 11
SharedPreferences is used to store whether the onboarding process is complete persistently. When the app starts, it checks SharedPreferences to see if onboardingComplete
is set to true
; if not, it defaults to showing the OnboardingScreen; otherwise, it displays the MainScreen.
import 'package:shared_preferences/shared_preferences.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
final bool onboardingComplete = prefs.getBool('onboardingComplete') ?? false;
runApp(MaterialApp(
home: onboardingComplete ? MainScreen() : OnboardingScreen(),
));
}
When the button is pressed, SharedPreferences updates onboardingComplete
to true
, and the app switches to the MainScreen, replacing the OnboardingScreen.
class OnboardingScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('onboardingComplete', true);
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => MainScreen()),
);
},
child: Text('Complete Onboarding'),
),
),
);
}
}
Once onboarding is marked complete (as stored in SharedPreferences), the MainScreen is shown
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Screen'),
),
body: Center(
child: Text('Welcome to the main screen!'),
),
);
}
}
Upvotes: 0
Reputation: 338
Using shared preference, you can show onboarding screen only one time.
static SharedPreferences? prefsInstance;
static void init() async {
prefsInstance = await prefsFuture;
}
set preference while completing onboarding screen Or last page's on click of button which move to dashboard or next screen after done onboarding.
prefsInstance!.setBool("IS_FIRST_INSTALLED", true);
Now get preference in splash and check if onboarding already seen or not.
if (SharedPrefUtils.getSharedPreference(IS_FIRST_INSTALLED) == false) {
/// move to onboarding screen
/// onboarding is not seen yet.
} else {
/// move to dashboard/home screen - onboarding is already seen
}
static Future<dynamic> getSharedPreference(String key) async {
dynamic value;
if (prefsInstance == null) {
var instance = await prefsFuture;
value = instance!.get(key);
} else {
value = get(key);
}
return value;
}
Upvotes: 1
Reputation: 957
As other answers are recommending the use of SharedPreferences or LocalSave, it works fine when you don't have any user account.
If you have user account and a database you should save this status in their profile so even if they install the application on a new device they don't have the onboarding again that could cause issues if you set some specific data that should only be accessed once by the user.
You basically have a bool hasCompletedOnboarding
set to false
when creating the user and you update it once he finishes the onboarding.
Then as FDuhen specified you show or not the Onboarding.
Upvotes: 5
Reputation: 35
You Can Use this Library
you will be able to save the data locally by configuring it only once
Upvotes: 2
Reputation: 4836
The common way to handle this is to use the SharedPreferences library
1- When displaying the onboarding, store a bool
like hasSeenOnboarding
in the SharedPreferences with the value true
2- Right before displaying the onboarding, fetch the bool hasSeenOnboarding
from the preferences.
If it's false
, you can display the onboarding, otherwise you should skip it
Upvotes: 12