简体   繁体   中英

Implementing BottomNavigationBar in Flutter bloc

I am new to Flutter so this might be a very simple fix. I am trying to implement a BottomNavigationBar following two different tutorials. I am receiving the following error:

2021-02-17 17:35:49.264849-0500 Runner[63966:16085302] flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
2021-02-17 17:35:49.265632-0500 Runner[63966:16085302] flutter: The following StackOverflowError was thrown building _FocusMarker:
2021-02-17 17:35:49.267493-0500 Runner[63966:16085302] flutter: Stack Overflow
2021-02-17 17:35:49.271329-0500 Runner[63966:16085302] flutter:
2021-02-17 17:35:49.271605-0500 Runner[63966:16085302] flutter: The relevant error-causing widget was:
2021-02-17 17:35:49.272835-0500 Runner[63966:16085302] flutter:   MaterialApp file:///Users/devdsk/Desktop/event_flutter/lib/app.dart:57:12
2021-02-17 17:35:49.273567-0500 Runner[63966:16085302] flutter:
2021-02-17 17:35:49.274329-0500 Runner[63966:16085302] flutter: When the exception was thrown, this was the stack:
2021-02-17 17:35:49.275107-0500 Runner[63966:16085302] flutter: #0      RangeError.checkValidRange

In my main.dart, I import my repositories like so:

void main() {
  runApp(App(
    authenticationRepository: AuthenticationRepository(),
    userRepository: UserRepository(),
    dashboardRepository: DashboardRepository(),
    eventRepository: EventRepository(),
  ));
}

And then I build my widget in app.dart. The app starts with an authentication prompt (login/register), once successfully signed in, it should navigate to a Home Screen that shows the bottom navigation bar. The relevant code for app.dart is below.

class App extends StatelessWidget {
  const App({
    Key key,
    @required this.authenticationRepository,
    @required this.userRepository,
    @required this.dashboardRepository,
    @required this.eventRepository,
  })  : assert(authenticationRepository != null),
        assert(userRepository != null),
        super(key: key);

  final AuthenticationRepository authenticationRepository;
  final UserRepository userRepository;
  final DashboardRepository dashboardRepository;
  final EventRepository eventRepository;

  @override
  Widget build(BuildContext context) {
    return RepositoryProvider.value(
      value: authenticationRepository,
      child: BlocProvider(
        create: (_) => AuthenticationBloc(
          authenticationRepository: authenticationRepository,
          userRepository: userRepository,
        ),
        child: AppView(),
      ),
    );
  }
}

class AppView extends StatefulWidget {
  @override
  _AppViewState createState() => _AppViewState();
}

class _AppViewState extends State<AppView> {
  final _navigatorKey = GlobalKey<NavigatorState>();

  NavigatorState get _navigator => _navigatorKey.currentState;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider<BottomNavigationBloc>(
        create: (context) => BottomNavigationBloc(
          dashboardRepository: DashboardRepository(),
          eventRepository: EventRepository(),
        )..add(AppStarted()),
        child: AppView(),
      ),
      navigatorKey: _navigatorKey,
      builder: (context, child) {
        return BlocListener<AuthenticationBloc, AuthenticationState>(
          listener: (context, state) {
            switch (state.status) {
              case AuthenticationStatus.authenticated:
                _navigator.pushAndRemoveUntil<void>(
                  HomePage.route(),
                  (route) => false,
                );
                break;
              case AuthenticationStatus.unauthenticated:
                _navigator.pushAndRemoveUntil<void>(
                  LoginPage.route(),
                  (route) => false,
                );
                break;
              default:
                break;
            }
          },
          child: child,
        );
      },
      onGenerateRoute: (_) => SplashPage.route(),
    );
  }
}

I am pretty sure it is simple. However my attempts to fix the logical error just replaces the old ones with new ones.

Thanks,

You have a cyclic dependency in your AppView widget:

class AppView extends StatefulWidget {
  @override
  _AppViewState createState() => _AppViewState();
}

class _AppViewState extends State<AppView> {
  final _navigatorKey = GlobalKey<NavigatorState>();

  NavigatorState get _navigator => _navigatorKey.currentState;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider<BottomNavigationBloc>(
        ...,
        child: AppView(),
      ),
      ...
    );
  }
}

AppView_AppViewStateAppView

I am new to Flutter so this might be a very simple fix. I am trying to implement a BottomNavigationBar following two different tutorials. I am receiving the following error:

2021-02-17 17:35:49.264849-0500 Runner[63966:16085302] flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
2021-02-17 17:35:49.265632-0500 Runner[63966:16085302] flutter: The following StackOverflowError was thrown building _FocusMarker:
2021-02-17 17:35:49.267493-0500 Runner[63966:16085302] flutter: Stack Overflow
2021-02-17 17:35:49.271329-0500 Runner[63966:16085302] flutter:
2021-02-17 17:35:49.271605-0500 Runner[63966:16085302] flutter: The relevant error-causing widget was:
2021-02-17 17:35:49.272835-0500 Runner[63966:16085302] flutter:   MaterialApp file:///Users/devdsk/Desktop/event_flutter/lib/app.dart:57:12
2021-02-17 17:35:49.273567-0500 Runner[63966:16085302] flutter:
2021-02-17 17:35:49.274329-0500 Runner[63966:16085302] flutter: When the exception was thrown, this was the stack:
2021-02-17 17:35:49.275107-0500 Runner[63966:16085302] flutter: #0      RangeError.checkValidRange

In my main.dart, I import my repositories like so:

void main() {
  runApp(App(
    authenticationRepository: AuthenticationRepository(),
    userRepository: UserRepository(),
    dashboardRepository: DashboardRepository(),
    eventRepository: EventRepository(),
  ));
}

And then I build my widget in app.dart. The app starts with an authentication prompt (login/register), once successfully signed in, it should navigate to a Home Screen that shows the bottom navigation bar. The relevant code for app.dart is below.

class App extends StatelessWidget {
  const App({
    Key key,
    @required this.authenticationRepository,
    @required this.userRepository,
    @required this.dashboardRepository,
    @required this.eventRepository,
  })  : assert(authenticationRepository != null),
        assert(userRepository != null),
        super(key: key);

  final AuthenticationRepository authenticationRepository;
  final UserRepository userRepository;
  final DashboardRepository dashboardRepository;
  final EventRepository eventRepository;

  @override
  Widget build(BuildContext context) {
    return RepositoryProvider.value(
      value: authenticationRepository,
      child: BlocProvider(
        create: (_) => AuthenticationBloc(
          authenticationRepository: authenticationRepository,
          userRepository: userRepository,
        ),
        child: AppView(),
      ),
    );
  }
}

class AppView extends StatefulWidget {
  @override
  _AppViewState createState() => _AppViewState();
}

class _AppViewState extends State<AppView> {
  final _navigatorKey = GlobalKey<NavigatorState>();

  NavigatorState get _navigator => _navigatorKey.currentState;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider<BottomNavigationBloc>(
        create: (context) => BottomNavigationBloc(
          dashboardRepository: DashboardRepository(),
          eventRepository: EventRepository(),
        )..add(AppStarted()),
        child: AppView(),
      ),
      navigatorKey: _navigatorKey,
      builder: (context, child) {
        return BlocListener<AuthenticationBloc, AuthenticationState>(
          listener: (context, state) {
            switch (state.status) {
              case AuthenticationStatus.authenticated:
                _navigator.pushAndRemoveUntil<void>(
                  HomePage.route(),
                  (route) => false,
                );
                break;
              case AuthenticationStatus.unauthenticated:
                _navigator.pushAndRemoveUntil<void>(
                  LoginPage.route(),
                  (route) => false,
                );
                break;
              default:
                break;
            }
          },
          child: child,
        );
      },
      onGenerateRoute: (_) => SplashPage.route(),
    );
  }
}

I am pretty sure it is simple. However my attempts to fix the logical error just replaces the old ones with new ones.

Thanks,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM