簡體   English   中英

Flutter:如何將 GoRouter 與 Bloc 結合使用以從啟動畫面路由到登錄畫面

[英]Flutter: How to use GoRouter with Bloc to route from Splash Screen to Login Screen

所以我最近在我的應用程序中切換到 Go 路由器,因為它很容易實現。 但是我無法從初始屏幕移動到登錄屏幕。 我的啟動畫面中有邏輯,我可以在其中檢查用戶是否登錄。 根據用戶的身份驗證,屏幕會轉到登錄屏幕或主頁。

這是啟動畫面。

    class SplashScreen extends StatefulWidget {
  static const routeName = "/SplashScreen";

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

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

class _SplashScreenState extends State<SplashScreen>
    with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return BlocConsumer<AuthenticationBloc, AuthenticationState>(
      listener: (context, state) {
        if (kDebugMode) {
          print('Listener: $state');
        }
        Future.delayed(const Duration(seconds: 3), () {
          if (state.authStatus == AuthStatus.unAuthenticated) {
            GoRouter.of(context).go('/login');

            Navigator.pushNamed(context, SignUpScreen.routeName);
          } else if (state.authStatus == AuthStatus.authenticated) {
            //Navigator.popUntil(context, (route) => route.isFirst);
            Navigator.pushReplacementNamed(context, HomePage.routeName);
          }
        });
      },
      builder: (context, Object? state) {
        if (kDebugMode) {
          print('object: $state');
        }
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Text(
                  "Welcome to Musajjal",
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
                ),
                const SizedBox(
                  height: 20,
                ),
                Image.asset(
                  'assets/musajjalBlue.png',
                  width: 300,
                  height: 300,
                ),
                const SizedBox(
                  height: 20,
                ),
                const Text(
                  "Hifz ul Quran Records",
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
                ),
                const SizedBox(
                  height: 20,
                ),
                const CircularProgressIndicator(
                  color: Colors.blueGrey,
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

接下來,這個。 是我的 Go 路由器 function

GoRouter _router(AuthenticationBloc bloc) {
return GoRouter(
  routes: <GoRoute>[
    GoRoute(
      path: '/',
      builder: (context, state) => const SplashScreen(),
      routes: <GoRoute>[
        GoRoute(path: 'login', builder: (context, state) => LoginScreen()),
        GoRoute(
            path: 'signUp', builder: (context, state) => SignUpScreen()),
        GoRoute(path: 'homePage', builder: (context, state) => HomePage())
      ],
      redirect: (BuildContext context, GoRouterState state) {
        final isLoggedIn =
            bloc.state.authStatus == AuthStatus.authenticated;
        final isLoggingIn = state.location == '/login';
        print(isLoggedIn);

        if (!isLoggedIn && !isLoggingIn) return '/login';
        if (isLoggedIn && isLoggingIn) return '/homePage';
        return null;
      },
    ),
  ],
);

}

問題是該應用程序卡在啟動畫面上,並且不會前進到登錄屏幕。 請幫忙。

嘗試將重定向中的邏輯更改為

if (!isLoggedIn && !isLoggingIn) return '/login';
if (isLoggedIn) return '/homePage';

另外,考慮將登錄邏輯作為 OR 而不是 AND --optional

if (!isLoggedIn || !isLoggingIn) return '/login';

試試下面的代碼:

main.dart

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

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
        providers: [
          BlocProvider<AuthenticationBloc>(
            create: (context) => AuthenticationBloc), 👈 Specify the BlocProvider here
          ),
        ],
        child: MaterialApp(
            theme: customTheme(context),
            debugShowCheckedModeBanner: false,
            routerConfig: router,
  }

router.dart

final GoRouter router = GoRouter(routes: [
  GoRoute(
      path: "/",
      builder: (context, state) {
        return BlocBuilder<AuthCubit, AuthState>(
          buildWhen: (oldState, newState) {
            return oldState is AuthInitialState;
           },
          builder: (context, state) {
             if (state is AuthLoading) {
              // return const SplashScreen();           // alternative way
               context.goNamed(SplashScreen.routeName); 👈 Display your splash screen here and you can provide delay while changing state in your bloc
            }
            else if (state is AuthenticationUnauthenticated) {
               context.goNamed(LoginPage.routeName);  
            } else if (state is Authenticated) {
                context.goNamed(HomePage.routeName);           
             } else {
              return const Scaffold();
            }
          },
        );
      }),

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM