Flutter BloC 布尔更新状态

Posted

技术标签:

【中文标题】Flutter BloC 布尔更新状态【英文标题】:Flutter BloC boolean updating state 【发布时间】:2020-02-27 01:38:04 【问题描述】:

我想为我的应用程序实现一个欢迎屏幕,该屏幕能够从登录更改为注册,具有不同的表单和按钮,而无需更改屏幕上的某些小部件(例如背景)。 我尝试使用带有堆栈的相同脚手架,全部由 BlocProvider 包围。 WelcomeBloc 应负责登录和注册表单之间的表单更改。 loginBloc 和 registerBloc 应该负责管理这两种形式的状态和输入。 用户存储库用于谷歌登录等操作。

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 模式。

这是我的欢迎文件。

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';

【问题讨论】:

【参考方案1】:

要更新小部件状态,您需要 BlocBuilder 而不是 BlocProvider。

BlocProvider 为其子项提供一个块。 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(),
        );
    
  
);

希望对你有帮助

【讨论】:

这有帮助,但我必须用另一个welcomeBloc 的BlocProvider 包装registerBloc 和loginBloc 的两个BlocProvider。如果我不这样做,终端会说我在没有welcomeBloc 的上下文中调用BlocProvider.of(context) (当我按下切换按钮时)。谢谢。

以上是关于Flutter BloC 布尔更新状态的主要内容,如果未能解决你的问题,请参考以下文章

Flutter bloc:更新状态不会重新调用 BlocBuilder

Flutter BLOC 状态更新但始终为空值

更新示例计数器中的非立即状态 - BloC Flutter

Flutter 状态管理之Bloc上

Flutter 状态管理之Bloc上

Flutter 状态管理之Bloc上