使用集团更换屏幕

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

当状态改变时,我设法显示了一个小部件, 问题是当状态再次更改时,然后更改上下文,并在显示的小部件中调用builder函数。

所以我创建了一个继承的小部件,其中将包含该块,因此我可以从子小部件分派一个事件,使其在父级发生,然后根据状态显示其他小部件。

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,),)
    );
  }

  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。

etric520 回答:使用集团更换屏幕

我解决了这个问题。

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

@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,child: BlocBuilder<SignupBloc,SignupState>(
                builder: (context,state) => _signupBuilder(context,)
            )
        );
      )
    );
  }

然后我使用此行引用了bloc提供商

BlocProvider.of<SignupBloc>(context)
本文链接:https://www.f2er.com/3129367.html

大家都在问