Flutter BloC 布尔更新状态
Flutter BloC boolean updating state
我想为我的应用程序实现一个欢迎屏幕,它能够使用不同的表单和按钮从登录更改为注册,而无需更改屏幕上的某些小部件(例如背景)。
我尝试将同一个脚手架与堆栈一起使用,所有这些都被 BlocProvider 包围。 welcomeBloc 应该负责登录和注册表单之间的表单更改。 loginBloc 和 registerBloc 应该负责管理两种形式的状态和输入。
用户存储库用于使用 google 登录等操作。
class WelcomeScreen extends StatefulWidget {
@override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
LoginBloc _loginBloc;
RegisterBloc _registerBloc;
WelcomeBloc _welcomeBloc;
UserRepository _userRepository = UserRepository();
@override
void initState() {
_loginBloc = LoginBloc(userRepository: _userRepository);
_registerBloc = RegisterBloc(userRepository: _userRepository);
_welcomeBloc = WelcomeBloc();
super.initState();
}
@override
Widget build(BuildContext context) {
return BlocProvider(
bloc: _welcomeBloc,
child: Scaffold(
backgroundColor: Colors.black,
resizeToAvoidBottomPadding: false,
body: Stack(
children: <Widget>[
Opacity(opacity: 0.6, child: Background()),
Padding(
padding: const EdgeInsets.only(top: 130, left: 20),
child: Text(
"Welcome.",
style: welcomeStyleBig,
),
),
_welcomeBloc.getLogin
? BlocProvider(
bloc: _loginBloc,
child: LoginForm(
userRepository: _userRepository,
),
)
: BlocProvider(
bloc: _registerBloc,
child: RegisterForm(),
),
],
),
),
);
}
}
我试图通过在 WelcomeBloc 中使用布尔变量 _isLogin 来实现表单的更改,但是当我点击负责更新的按钮时,在我热重新加载应用程序之前没有任何反应。可能是我对bloc pattern不是很了解
这是我的欢迎 bloc 文件。
welcome_bloc.dart
class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
@override
WelcomeState get initialState => InitialWelcomeState();
bool _isLogin = true;
bool get getLogin => _isLogin;
@override
Stream<WelcomeState> mapEventToState(
WelcomeEvent event,
) async* {
if (event is SwitchToLogin) {
_isLogin = true;
yield WelcomeLogin();
}
if (event is SwitchToRegister) {
_isLogin = false;
yield WelcomeRegister();
}
}
}
welcome_event.dart
abstract class WelcomeEvent extends Equatable {
WelcomeEvent([List props = const []]) : super(props);
}
class SwitchToLogin extends WelcomeEvent {
@override
String toString() {
return "Switch to Login";
}
}
class SwitchToRegister extends WelcomeEvent {
@override
String toString() {
return "Switch to Register";
}
}
welcome_state.dart
abstract class WelcomeState extends Equatable {
WelcomeState([List props = const []]) : super(props);
}
class InitialWelcomeState extends WelcomeState {
@override
List<Object> get props => [];
}
class WelcomeLogin extends WelcomeState {
@override
String toString() => 'Welcome Login';
}
class WelcomeRegister extends WelcomeState {
@override
String toString() => 'Welcome Register';
}
要更新小部件状态,您需要 BlocBuilder 而不是 BlocProvider。
- BlocProvider 为其子项提供一个 bloc。
- BlocBuilder 负责构建小部件以响应新状态。
你也在使用
BlocProvider(
bloc: _loginBloc,
BlocProvider 获取 builder:
作为参数而不是 `bloc:'
我不明白你怎么不报错。
在你的情况下,你可以像下面的代码那样做。
(可能有很多错误,但你可以理解)
您正在使用的 flutter_bloc 库的文档也非常好。
我建议您阅读它并查看示例
所以我认为解决方案应该是这样的:
BlocBuilder<WelcomeEvent, WelcomeState>(
bloc: _welcomeBloc, // provide the local bloc instance
builder: (context, state) {
if(state is SwitchToLogin){
return BlocProvider(
builder: (BuildContext context) => _loginBloc,
child: LoginForm(
userRepository: _userRepository,
),
);
}
else{
return BlocProvider(
builder: (BuildContext context) =>_registerBloc,
child: RegisterForm(),
);
}
}
);
希望对您有所帮助
我想为我的应用程序实现一个欢迎屏幕,它能够使用不同的表单和按钮从登录更改为注册,而无需更改屏幕上的某些小部件(例如背景)。 我尝试将同一个脚手架与堆栈一起使用,所有这些都被 BlocProvider 包围。 welcomeBloc 应该负责登录和注册表单之间的表单更改。 loginBloc 和 registerBloc 应该负责管理两种形式的状态和输入。 用户存储库用于使用 google 登录等操作。
class WelcomeScreen extends StatefulWidget {
@override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
LoginBloc _loginBloc;
RegisterBloc _registerBloc;
WelcomeBloc _welcomeBloc;
UserRepository _userRepository = UserRepository();
@override
void initState() {
_loginBloc = LoginBloc(userRepository: _userRepository);
_registerBloc = RegisterBloc(userRepository: _userRepository);
_welcomeBloc = WelcomeBloc();
super.initState();
}
@override
Widget build(BuildContext context) {
return BlocProvider(
bloc: _welcomeBloc,
child: Scaffold(
backgroundColor: Colors.black,
resizeToAvoidBottomPadding: false,
body: Stack(
children: <Widget>[
Opacity(opacity: 0.6, child: Background()),
Padding(
padding: const EdgeInsets.only(top: 130, left: 20),
child: Text(
"Welcome.",
style: welcomeStyleBig,
),
),
_welcomeBloc.getLogin
? BlocProvider(
bloc: _loginBloc,
child: LoginForm(
userRepository: _userRepository,
),
)
: BlocProvider(
bloc: _registerBloc,
child: RegisterForm(),
),
],
),
),
);
}
}
我试图通过在 WelcomeBloc 中使用布尔变量 _isLogin 来实现表单的更改,但是当我点击负责更新的按钮时,在我热重新加载应用程序之前没有任何反应。可能是我对bloc pattern不是很了解
这是我的欢迎 bloc 文件。
welcome_bloc.dart
class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
@override
WelcomeState get initialState => InitialWelcomeState();
bool _isLogin = true;
bool get getLogin => _isLogin;
@override
Stream<WelcomeState> mapEventToState(
WelcomeEvent event,
) async* {
if (event is SwitchToLogin) {
_isLogin = true;
yield WelcomeLogin();
}
if (event is SwitchToRegister) {
_isLogin = false;
yield WelcomeRegister();
}
}
}
welcome_event.dart
abstract class WelcomeEvent extends Equatable {
WelcomeEvent([List props = const []]) : super(props);
}
class SwitchToLogin extends WelcomeEvent {
@override
String toString() {
return "Switch to Login";
}
}
class SwitchToRegister extends WelcomeEvent {
@override
String toString() {
return "Switch to Register";
}
}
welcome_state.dart
abstract class WelcomeState extends Equatable {
WelcomeState([List props = const []]) : super(props);
}
class InitialWelcomeState extends WelcomeState {
@override
List<Object> get props => [];
}
class WelcomeLogin extends WelcomeState {
@override
String toString() => 'Welcome Login';
}
class WelcomeRegister extends WelcomeState {
@override
String toString() => 'Welcome Register';
}
要更新小部件状态,您需要 BlocBuilder 而不是 BlocProvider。
- BlocProvider 为其子项提供一个 bloc。
- BlocBuilder 负责构建小部件以响应新状态。
你也在使用
BlocProvider(
bloc: _loginBloc,
BlocProvider 获取 builder:
作为参数而不是 `bloc:'
我不明白你怎么不报错。
在你的情况下,你可以像下面的代码那样做。
(可能有很多错误,但你可以理解)
您正在使用的 flutter_bloc 库的文档也非常好。 我建议您阅读它并查看示例
所以我认为解决方案应该是这样的:
BlocBuilder<WelcomeEvent, WelcomeState>(
bloc: _welcomeBloc, // provide the local bloc instance
builder: (context, state) {
if(state is SwitchToLogin){
return BlocProvider(
builder: (BuildContext context) => _loginBloc,
child: LoginForm(
userRepository: _userRepository,
),
);
}
else{
return BlocProvider(
builder: (BuildContext context) =>_registerBloc,
child: RegisterForm(),
);
}
}
);
希望对您有所帮助