flutter 如何将构建上下文传递给navigator,以便能够跨页面访问相同的块示例?

iugsix8n  于 2023-05-08  发布在  Flutter
关注(0)|答案(2)|浏览(109)

我正在建立一个注册流程来练习flutter和blocks。
在我的应用程序中,我嵌套了基本url '/registration'的路由。我用我的blocprovider Package 了我的Material App。我想实现的是将phonenumber保存到我的初始路由中的状态,并在下面的页面中使用它。
目前,我的应用程序在初始路径中保存状态,但一旦它导航到下一个页面,就会创建一个新的块示例,因此我无法访问保存的状态。我认为我需要将现有的上下文传递给navigator的构建器。然而,我没有成功地以这种方式重构我的代码。我如何重构我的代码,使MaterialPageRoute的构建器回调不会给予我新的构建上下文?
谢谢大家!

这里是生成路由的父注册码:

class RegisterFlowState extends State<RegisterFlow> {
  final _navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Navigator(
        key: _navigatorKey,
        initialRoute: 'register/phonenumber',
        onGenerateRoute: _onGenerateRoute,
      ),
    );
  }
}

Route _onGenerateRoute(RouteSettings settings) {
  WidgetBuilder builder;
  switch (settings.name) {
    case 'register/phonenumber':
      builder = (_) => const CollectPhonenumberPage();
      break;
    case 'register/otp':
      builder = (_) => const OtpPage();
      break;
    default:
      throw Exception('Invalid route: ${settings.name}');
  }
  return MaterialPageRoute<void>(builder: builder, settings: settings);
}

保存状态推送到新url的第一页。

ElevatedButton(
            onPressed: () {
              phoneNumberBloc.add(UpdatePhoneNumberEvent(phoneController.text));
              Navigator.of(context).pushReplacementNamed('register/otp')
            },
            child: const Text('Kaydet'),
          ),

第二页我想消费状态

BlocBuilder<PhoneNumberBloc, PhoneNumberState>(
            builder: (context, state) => Text('${state.data}'),
          )

我查阅了这些链接并尝试了几个解决方案,但没有一个解决了我的问题texttext

xn1cxnb4

xn1cxnb41#

可以将bloc传递给blocProvider。value:

就像这样:

Route _onGenerateRoute(RouteSettings settings) {
  switch (settings.name) {
    case 'register/phonenumber':
      return MaterialPageRoute<void>(
        builder: (_) => const CollectPhonenumberPage(),
      );
    case 'register/otp':
      return BlocProvider.value(
        value: context.read<PhoneNumberBloc>(),
        child: const OtpPage(),
      );
    default:
      throw Exception('Invalid route: ${settings.name}');
  }
}
dwbf0jvd

dwbf0jvd2#

可以定义一个函数,以当前上下文为参数,返回应该显示的widget

  • 示例:*
class RegisterFlowState extends State<RegisterFlow> {
  final _navigatorKey = GlobalKey<NavigatorState>();
  final phoneNumberBloc = PhoneNumberBloc();

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

  Widget _wrapWithBlocProvider(Widget child) {
    return BlocProvider.value(
      value: phoneNumberBloc,
      child: child,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Navigator(
        key: _navigatorKey,
        initialRoute: 'register/phonenumber',
        onGenerateRoute: (RouteSettings settings) {
          WidgetBuilder builder;
          switch (settings.name) {
            case 'register/phonenumber':
              builder = (BuildContext context) {
                return _wrapWithBlocProvider(const CollectPhonenumberPage());
              };
              break;
            case 'register/otp':
              builder = (BuildContext context) {
                return _wrapWithBlocProvider(const OtpPage());
              };
              break;
            default:
              throw Exception('Invalid route: ${settings.name}');
          }
          return MaterialPageRoute<void>(builder: builder, settings: settings);
        },
      ),
    );
  }
}

相关问题