首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用bloc更改屏幕

使用bloc更改屏幕
EN

Stack Overflow用户
提问于 2019-11-10 19:57:18
回答 1查看 1.3K关注 0票数 0

我正在尝试使用bloc切换屏幕(无状态小部件),当使用BlocBuilder根据状态输出不同的小部件时,上下文将更改为显示的新小部件。在新的小部件中调用状态侦听器。

当状态改变时,我设法显示了一个小部件,问题是当状态再次改变时,上下文被改变,并且在所显示的小部件中调用构建器函数。

因此,我创建了一个包含该块的inheritedWidget,这样我就可以从子部件中分派一个事件在父部件上发生,然后根据状态显示不同的部件。

代码语言:javascript
复制
class SignupViewManager extends InheritedWidget {
  final SignupBloc bloc;
  final Widget child;

  SignupViewManager({Key key, this.child, this.bloc}) : super(key: key, child: child);

  static SignupViewManager of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(SignupViewManager) as SignupViewManager);
  }

  @override
  bool updateShouldNotify(SignupViewManager oldWidget) {
    return true;
  }
}

class SignupHomePage extends StatelessWidget {
  final SignupBloc signupBloc = SignupBloc();

  SignupHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SignupViewManager(
        bloc: SignupBloc(),
        child: BlocProvider<SignupBloc>(
          builder: (context) => signupBloc,
          child: BlocBuilder<SignupBloc, SignupState>(
              builder: (context, state) => _signupBuilder(context, state),
              condition: (previousState, state) => _signupCondition(previousState, state),
        ),
      )
    );
  }

  Widget _signupBuilder(BuildContext context, SignupState state) {
    print("IN SIGNUP MAIN BUILDER $state");
    // Changing the UI based on the current state
    if (state is SignupInitial) { // Show credentials for initial state
      return SignupCredentials();
    } else if (state is SavedCredentials) { // Show Agreements after credentials has been saved.
      return SignupAgreements(user: state.user);
    }

    return Text("default");
  }
}

class SignupCredentials extends StatelessWidget {
  SignupBloc signupBloc;

  void _signup(email, password, confirmPassword) {
    if(password == confirmPassword) {
      signupBloc.add(SaveCredentials(email, password));
    } else {
      print("passwords do not match");
    }
  }

  Widget _bloc() {
    return BlocBuilder<SignupBloc, SignupState>(
        builder: (context, state) {
            print("IN SIGNUP credentials builder $state");

            if(state is SavedCredentials) {
            return SignupDetails();
            }

            return Text("${state.runtimeType}");
        },
    );
  }
}

因此,当状态设置为SignupInitial时,应该会出现SignupCredentials无状态小部件。然后,当用户输入凭据并提交它们时,将调度SavedCredentials事件,并显示SignupAgreements。但实际情况是,SignupCredentials构建器接收的是新状态,而不是SignupHomePage。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-11 01:04:34

我解决了这个问题。

我将块提供程序更改为SignupBloc类型。

代码语言:javascript
复制
@override
  Widget build(BuildContext context) {
    return AuthenticationPageLayout(
      color: Colors.white,
      opacity: 0.05,
      child: SignupViewManager(
        child: BlocProvider<SignupBloc>(
            builder: (context) => SignupBloc(),
            child: BlocListener<SignupBloc, SignupState>(
                listener: (context, state) => _signupListener(context, state),
                condition: (previousState, state) => _signupCondition(previousState, state),
                child: BlocBuilder<SignupBloc, SignupState>(
                builder: (context, state) => _signupBuilder(context, state),
                condition: (previousState, state) => _signupCondition(previousState, state),
                )
            )
        );
      )
    );
  }

然后,我使用下面这行代码引用了块提供程序

代码语言:javascript
复制
BlocProvider.of<SignupBloc>(context)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58788407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档