import 'dart:async'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; @immutable abstract class MaterialAppWithIntro extends StatelessWidget { const MaterialAppWithIntro( this.name, this.theme, this.routes, this.introWidget, this.continueWidget, this.prefsKey, { super.key, }); final String name; final ThemeData theme; final Map routes; final WidgetBuilder introWidget; final WidgetBuilder continueWidget; final String prefsKey; @override Widget build(BuildContext context) { return MaterialApp( home: MaterialAppWithIntroHome(introWidget, continueWidget, prefsKey), title: name, theme: theme, routes: routes, ); } } class MaterialAppWithIntroHome extends StatefulWidget { const MaterialAppWithIntroHome( this.introWidget, this.continueWidget, this.prefsKey, { super.key, }); final WidgetBuilder introWidget; final WidgetBuilder continueWidget; final String prefsKey; @override // ignore: library_private_types_in_public_api _MaterialAppWithIntroState createState() => _MaterialAppWithIntroState(); } class _MaterialAppWithIntroState extends State { _MaterialAppWithIntroState(); late final WidgetBuilder introWidget = widget.introWidget; late final WidgetBuilder continueWidget = widget.continueWidget; late final String prefsKey = widget.prefsKey; @override void initState() { super.initState(); Timer(const Duration(milliseconds: 1000), () { checkFirstStart(); }); } // https://stackoverflow.com/questions/50654195/flutter-one-time-intro-screen Future checkFirstStart() async { final String initialWizardKey = prefsKey; final SharedPreferences prefs = await SharedPreferences.getInstance(); final bool showInitialWizard = prefs.getBool(initialWizardKey) ?? true; if (showInitialWizard) { await prefs.setBool(initialWizardKey, false); if (mounted) { await Navigator.of(context) .pushReplacement(MaterialPageRoute(builder: introWidget)); } } else { if (mounted) { await Navigator.of(context) .pushReplacement(MaterialPageRoute(builder: continueWidget)); } } } @override Widget build(BuildContext context) { return const Scaffold( body: Center( child: CircularProgressIndicator(), ), ); } }