【问题标题】:Flutter BloC boolean updating stateFlutter BloC 布尔更新状态
【发布时间】: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';
}

【问题讨论】:

    标签: flutter state bloc


    【解决方案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) (当我按下切换按钮时)。谢谢。
    猜你喜欢
    • 2021-03-19
    • 2020-10-10
    • 2022-08-11
    • 2020-08-03
    • 2020-04-28
    • 2021-08-02
    • 2021-01-06
    • 2023-03-13
    • 2020-05-06
    相关资源
    最近更新 更多