flutterflutter-blocflutter-go-router

Flutter : how to change automatically from splash screen to next screen?


I'm having an issue with moving from the splash screen to the next screen in my application. When the app first starts, I want to display a splash screen, and after that I try to use pushReplacement to go from the splash screen to the next screen.

How to implement this method correctly?

-route

GoRouter goRouter(AuthBloc authBloc) {
  return GoRouter(
    navigatorKey: GlobalKey<NavigatorState>(),
    routes: <GoRoute>[
      GoRoute(
          path: '/',
          name: 'intitial',
          builder: (context, state) => const SplashScreen(),
          routes: <GoRoute>[
            GoRoute(
                path: '/login',
                name: 'login',
                builder: (context, state) {
                  return const LoginPage();
                }),
            GoRoute(
              path: '/homepage',
              name: 'homepage',
              builder: (context, state) {
                return BlocProvider<WeatherBloc>(
                  create: (context) => WeatherBloc(),
                  child: MyHomepage(dateTime: DateTime.now()),
                );
              },
              routes: [
                GoRoute(
                    path: '/gempa',
                    name: 'gempa',
                    builder: (context, state) {
                      return BlocProvider<GempaBloc>(
                        create: (context) => GempaBloc(),
                        child: const GempaPage(),
                      );
                    })
              ],
            )
          ],
          redirect: (context, state) async {
            bool islogin = true;
            bool hastoken = await authBloc.firebaseAuthService.hasToken();
            return hastoken && islogin ? AppRoute.homepage : AppRoute.login;
          }),
    ],
  );
}

-main

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();
  // await dotenv.load();
  Bloc.observer = Observer();
  // await Firebase.initializeApp();
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final FirebaseAuthService firebaseAuthService = FirebaseAuthService();
  final AuthBloc authBloc = AuthBloc(FirebaseAuthService());

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) =>
          AuthBloc(firebaseAuthService)..add(CheckSignStatus()),
      child: BlocListener<AuthBloc, AuthState>(
        listener: (context, state) {
          if (state is AuthUser) {
            context.go(AppRoute.homepage);
          } else if (state is NonAuthUser) {
            context.go(AppRoute.login);
          }
        },
        child: MaterialApp.router(
          title: 'sample',
          routerConfig: goRouter(authBloc),
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            textTheme:
                GoogleFonts.poppinsTextTheme(Theme.of(context).textTheme),
          ),
        ),
      ),
    );
  }
}

I've read the documentation, but I'm still confused


Solution

  • You just need to add Future.delay for time you need for showing splash screen and navigate to other screen. Below code is for manually if you want to add splash screen but through flutter_native_splash you can generate your own splash screen.

    import 'package:flutter/material.dart';
    
    class SplashScreen extends StatefulWidget {
      const SplashScreen({super.key});
    
      @override
      State<SplashScreen> createState() => _SplashScreenState();
    }
    
    class _SplashScreenState extends State<SplashScreen> {
    
    
      @override
      void initState() {
        super.initState();
        WidgetsFlutterBinding.ensureInitialized();
        Future.delayed(const Duration(seconds: 3), () {
          Navigator.pushReplacementNamed(context, R.onBoarding);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return AppBackground(
            child: Center(
              child: Image.asset(
                ImagesAsset.appLogo,
                height: 55.h,
                width: 245.w,
                fit: BoxFit.contain,
              ),
            ),
          ),
        );
      }
    }