使用Bloc的Flutter导航:用于从导航器推开路由的上下文必须是导航窗口小部件的后代



我正在使用bloc,我需要从pageone到pagetwo,并能够使用返回按钮返回,我不知道这是否是解决此问题的正确方法。当功能 _navigateTopage2 称为

时,我也会遇到错误。

用于从导航器推出或弹出路由的上下文必须是导航窗口小部件后代的小部件的上下文。

class SimpleBlocDelegate extends BlocDelegate {
  @override
  void onTransition(Transition transition) {
     print(transition);
  }
  @override
  void onError(Object error, StackTrace stacktrace) {
      print(error);
   }
}

void main() {
  BlocSupervisor().delegate = SimpleBlocDelegate();
  runApp(MyApp(userRepository: UserRepository(GuriApi())));
}
class MyApp extends StatefulWidget {
  final UserRepository userRepository;
  MyApp({Key key, @required this.userRepository}) : super(key: key);
  @override
  State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
  AuthenticationBloc _authenticationBloc;
  UserRepository get _userRepository => widget.userRepository;
  @override
  void initState() {
    _authenticationBloc = AuthenticationBloc(userRepository: _userRepository);
    _authenticationBloc.dispatch(AppStarted());
    super.initState();
  }
  @override
  void dispose() {
    _authenticationBloc.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return BlocProvider<AuthenticationBloc>(
      bloc: _authenticationBloc,
      child: MaterialApp(
        theme: new ThemeData(
            fontFamily: 'Monserrat',
            primaryColor: Colors.lightBlue[50],
            accentColor: Colors.white),
        home: BlocBuilder<AuthenticationEvent, AuthenticationState>(
          bloc: _authenticationBloc,
          builder: (BuildContext context, AuthenticationState state) {
            if (state is AuthenticationUninitialized) {
              return SplashPage();
            }
            if (state is AuthenticationAuthenticated) {
              return Home(userRepository: _userRepository);
            }
            if (state is AuthenticationUnauthenticated) {
              return LoginPage(userRepository: _userRepository);
            }
            if (state is AuthenticationLoading) {
              return LoadingIndicator();
            }
            if (state is PageOneSelected) {
              return PageOne();
            }
            if (state is PageTwoSelected) {
              _navigateToPage2();
            }
          },
        ),
      ),
    );
  }
  _navigateToPage2() {
    Navigator.of(context).push<bool>(
        MaterialPageRoute(
            builder: (BuildContext context) =>
                PageTwo(userRepository: _userRepository)));
  }
}

我认为最好通过订阅Initstate的Bloc状态变化来处理导航:

@override
void initState() {
    super.initState();
    bloc.state.listen((state) {
        if (state is PageOneSelected) {
            _navigateToPage2();
        } else if (state is PageTwoSelected) {
            _navigateToPage2();
        }
    });
}

在构建方法中显示其他一些小部件。代码中发生错误,因为blocbuilder必须返回小部件,但是如果pagetwoselectectectected状态,您什么也没返回。

有必要在小部件中执行这样的事情:

     if (state is PageTwoSelected) {
         WidgetsBinding.instance.addPostFrameCallback((_){
            Navigator.push(context, 
              MaterialPageRoute(builder: (context) =>
                PageTwo(userRepository: _userRepository))
            );
         });
     }

这是必要的,因为如果导航在仍在建造小部件时发生(处于肮脏状态)时,flutter将抛出异常。

通过将其嵌套在AddPostFrameCallback的回调中,您基本上是在说小部件完成构建后,然后执行导航代码。

您可以在这里阅读更多有关它的信息,评论中有解释。

相关内容

  • 没有找到相关文章

最新更新