使用 bloc 更改屏幕
Posted
技术标签:
【中文标题】使用 bloc 更改屏幕【英文标题】:Changing screens using bloc 【发布时间】:2020-03-06 09:01:24 【问题描述】:我正在尝试使用 bloc 切换屏幕(无状态小部件), 当使用 BlocBuilder 根据状态输出不同的小部件时,上下文将更改为显示的新小部件。 在新小部件中调用状态侦听器。
当状态改变时,我设法显示了一个小部件, 问题是当状态再次发生变化时,上下文发生了变化,并且在显示的小部件中调用了构建器函数。
所以我创建了一个包含该块的继承小部件,因此我可以从子小部件调度一个事件以在父小部件上发生,然后根据状态显示不同的小部件。
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。
【问题讨论】:
【参考方案1】:我解决了这个问题。
我将 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, state),
child: BlocBuilder<SignupBloc, SignupState>(
builder: (context, state) => _signupBuilder(context, state),
condition: (previousState, state) => _signupCondition(previousState, state),
)
)
);
)
);
然后我使用此行引用了 bloc 提供者
BlocProvider.of<SignupBloc>(context)
【讨论】:
以上是关于使用 bloc 更改屏幕的主要内容,如果未能解决你的问题,请参考以下文章