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(),
        );
    }
  }
);

希望对您有所帮助