我正在尝试使用bloc切换屏幕(无状态小部件),当使用BlocBuilder根据状态输出不同的小部件时,上下文将更改为显示的新小部件。在新的小部件中调用状态侦听器。
当状态改变时,我设法显示了一个小部件,问题是当状态再次改变时,上下文被改变,并且在所显示的小部件中调用构建器函数。
因此,我创建了一个包含该块的inheritedWidget,这样我就可以从子部件中分派一个事件在父部件上发生,然后根据状态显示不同的部件。
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。
发布于 2019-11-11 01:04:34
我解决了这个问题。
我将块提供程序更改为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, state),
child: BlocBuilder<SignupBloc, SignupState>(
builder: (context, state) => _signupBuilder(context, state),
condition: (previousState, state) => _signupCondition(previousState, state),
)
)
);
)
);
}然后,我使用下面这行代码引用了块提供程序
BlocProvider.of<SignupBloc>(context)https://stackoverflow.com/questions/58788407
复制相似问题