0

I was working in Flutter to make an app and I only want the onboarding screen to be seen once by users. I have watched several videos showing how to do this, but the problem is my home screen will always be the Splash Screen. I am not sure how to use Shared Preferences to have the onboarding screen shown once but to still have the splash screen show every time. I could really use some assistance :).

My code for main.dart:

int? isViewed;
Future <void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final prefs = await SharedPreferences.getInstance();
  final showLogin = prefs.getBool('showLogin') ?? false;
  Paint.enableDithering = true;
  await Firebase.initializeApp();

// This is for our onboarding screen
isViewed = prefs.getInt('onboard');

  runApp(MyApp(showLogin: showLogin));
}

class MyApp extends StatelessWidget {
  final bool showLogin;
  
  const MyApp({Key? key,
  required this.showLogin}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Strength',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        appBarTheme: const AppBarTheme(color: Colors.white,
        elevation: 0,
        brightness: Brightness.light,
        iconTheme: IconThemeData(color: Colors.black),
        textTheme: TextTheme(headline6: TextStyle(color: Color(0xff888888), fontSize: 18),
        )
      ),),
      home: const SplashScreen(),
    );
  }
}

Chunks of code for my onboarding screen:

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

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

class _OnboardingScreenState extends State<OnboardingScreen> {
  final controller = PageController();
  bool isLastPage = false;

  @override
  void dispose() {
    controller.dispose();

    super.dispose();
  }

  _storeOnboardingInfo() async {
    int isViewed = 0;
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setInt('onBoard', isViewed);
  }
  
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
.
.
.
TextButton(
          style: TextButton.styleFrom(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(0),
            ),
            primary: Colors.white,
            backgroundColor: const Color(0xff31708c),
            minimumSize: const Size.fromHeight(60)
          ),
          child: Text(
            'Get Started',
            style: GoogleFonts.montserrat(
              fontSize: 24,
              fontWeight: FontWeight.w600),
          ),
          onPressed: () async {
            final prefs = await SharedPreferences.getInstance();
            prefs.setBool('showLogin', true);
            await _storeOnboardingInfo();

            Navigator.of(context).pushReplacement(
              PageTransition(
                type: PageTransitionType.fade,
                duration: const Duration(milliseconds: 500),
                child: LandingScreen()
              )
            );
          }
        )

Code for my Splash screen:

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

  @override
  _SplashScreenState createState() => _SplashScreenState();

}

class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMixin{
  late AnimationController _screenController;

  @override
  void initState() {
    super.initState();
    _screenController = AnimationController(vsync: this);

  }

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Container(
      height: double.infinity,
      width: double.infinity,
      child: Lottie.asset('assets/lottie/splashScreen.lottie.json',
      fit: BoxFit.fill,
      controller: _screenController,
      onLoaded: (composition) {
        _screenController
        ..duration = composition.duration
        ..forward().whenComplete(() => 
        Navigator.of(context).pushReplacement(
          PageTransition(
            type: PageTransitionType.fade,
            duration: const Duration(milliseconds: 1800),
            child: const OnboardingScreen()
          )
        ));
      }
      )
    )
  );
}
}
Ta-Ty
  • 77
  • 1
  • 15
  • Please share the code of of your Splash Screen – Vipul Chauhan Sep 05 '22 at 18:27
  • @VipulChauhan I have shared my code for my splash screen :) – Ta-Ty Sep 05 '22 at 19:37
  • You have to add a condition if the user has already seen the onboarding or not for example ==> "child: isOnboardingDone?LoginScreen():const OnboardingScreen()" For this you can use the Shared preference "https://pub.dev/packages/shared_preferences" – Vipul Chauhan Sep 06 '22 at 17:34
  • I'm sorry I'm confused. I have the beginning of SharedPreferences used in my main dart and onboarding screen, where I have a variable called isViewed. When I do as you suggest for page navigation from my splash screen, it does not work – Ta-Ty Sep 06 '22 at 21:51

2 Answers2

1

You can check the shared preference value in the Splash Screen and redirect the user to the OnBoardingScreen or LandingScreen.

import 'package:custom_form_field/src/form_screen.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

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

class _SplashScreenState extends State<SplashScreen>
    with TickerProviderStateMixin {
  late AnimationController _screenController;

  @override
  void initState() {
    super.initState();
    _screenController = AnimationController(vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
            height: double.infinity,
            width: double.infinity,
            child: Lottie.asset('assets/lottie/splashScreen.lottie.json',
                fit: BoxFit.fill,
                controller: _screenController, onLoaded: (composition) {
              _screenController
                ..duration = composition.duration
                ..forward().whenComplete(() async {
                      SharedPreferences prefs = await SharedPreferences.getInstance();
                  // check shared preference and show particular screen
                 
                });
            })));
  }
}

You can check the shared preference value at initState and do the logic after animation complete as well. Also you can check login state from shared preference here and show login page if needed.

umuieme
  • 729
  • 6
  • 20
0

Make a global variable :

Global.dart

library my_prj.globals;
bool newUser = true;

main.dart

globals.newUser == true ? LandingPage() : LoginPage()

signup.dart

Here i am passing the variable

globals.newUser = false;

along with Username or Password fields.

After then your value will be permanently set false until and unless you make a change on it.

  • I'm sorry, I don't understand what you mean at all. Could you explain again? – Ta-Ty Sep 06 '22 at 21:49
  • Step 1 : Make a Global Bool Value and pass true while Signup Screen .... Step 2: Make sure Bool Value would be set false by default. Step3 : Make a Condition that if the bool value is true then show Splash Screen else Login Screen ........... I will share some demo code – Muhammad Rameez Sep 07 '22 at 18:00