Flutter自动路由:如何以编程方式设置初始路由?

4

我有一个登录界面和一个主界面。一旦用户登录,它会将用户重定向到主界面。然而,我有一个块来检查用户是否已经通过认证,如果是,则直接将用户重定向到主界面。

然而,它并没有按预期工作。 "isLoggedIn" 布尔值发生变化,但UI并未做出反应。如何解决这个问题?

以下是代码:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:harnasik/core/router/app_router.gr.dart';
import 'package:harnasik/core/style/custom_colors.dart';
import 'package:harnasik/features/authorization/presentation/blocs/log_in/log_in_bloc.dart';
import 'package:harnasik/generated/l10n.dart';
import 'package:harnasik/injection_container.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await InjectionContainer().init();
  runApp(const HarnasikApp());
}

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

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

class _HarnasikAppState extends State<HarnasikApp> {
  late final LogInBloc logInBloc;
  late bool isLoggedIn;
  final AppRouter _appRouter = sl();

  @override
  void initState() {
    logInBloc = sl();
    super.initState();
    isLoggedIn = false;
    logInBloc..add(CheckIfUserLoggedInEvent());
  }

  @override
  void dispose() {
    logInBloc.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener(
      bloc: logInBloc,
      listener: (context, state) {
        if (state is LoggedInState) {
          isLoggedIn = true;
        } else if (state is LogInErrorState) {
          print('Error'); // For tests only
        }
      },
      child: MaterialApp.router(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: CustomColors.blue,
          fontFamily: 'Lato',
        ),
        routerDelegate: _appRouter.delegate(
          initialRoutes: [
            if (!isLoggedIn) const LogInScreen() else const HomeScreen(),
          ],
        ),
        routeInformationParser: _appRouter.defaultRouteParser(),
        localizationsDelegates: const [
          S.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate
        ],
        supportedLocales: S.delegate.supportedLocales,
      ),
    );
  }
}

你解决了这个问题吗? - Martin Reindl
2个回答

3
我使用了一个自动路由守卫来解决这个问题,代码如下:
/// An auto_route guard object that routes the user to our landing page if
/// signed in and to the home page if not signed in 
class GetInitialRoute extends AutoRouteGuard {

  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) {

    // Here we check if the user is logged in using FirebaseAuth (not currentUser --> 
    // not logged in)
    if (FirebaseAuth.instance.currentUser == null) {
      // if we do not have a user yet, we resume navigation to the sign in page 
      // with path: '/'
      resolver.next(true);
    } else {
      // if we already have a logged in user, we push them to our home page
      router.push(const HomeRoute());
    }
  }
}

请阅读关于auto_route身份验证的文章链接以及关于route_guards的文章链接,以了解更多信息。这些文章还解释了如何将守卫应用于您的路由。

-3
class MyTasks extends StatelessWidget {
  AppRoute approute = AppRoute();
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => BottomnavigationCubit(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        onGenerateRoute: approute.myroutes,
      ),
    );
  }
}

class AppRoute {
  
  Route myroutes(RouteSettings settings) {
    switch (settings.name) {
      case "/":
        return MaterialPageRoute(
            builder: (_) => Home());
      case "/product":
        return MaterialPageRoute(builder: (_) => Product());
      
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接