mapEventToState不使用BLOC模式触发,颤振

时间:2020-03-24 22:13:41

标签: flutter dart bloc

我正在使用Flutter开发应用程序,并决定使用Google推荐的块模式,但是我定义的事件从未触发过。我将事件定义为检查连接是否发生时,布尔值从控制器返回到视图。

下面是相关代码

登录controller.dart

import 'package:XXXXX/connection.dart';
import 'package:bloc/bloc.dart';
import 'package:connectivity/connectivity.dart';


class LoginBloc extends Bloc<Connectivity,bool> {
  @override
  bool get initialState => false;

  @override
  Stream<bool> mapEventToState(Connectivity event) async*{
    // TODO: implement mapEventToState
    switch(await event.checkConnectivity()){
      case ConnectivityResult.mobile:
      yield true;
      break;
      case ConnectivityResult.wifi:
      yield true;
      break;
      case ConnectivityResult.none:
      yield false;

    }
  }
}
class LoginWidget extends StatefulWidget {
  @override
  LoginWidgetState createState() {
    return LoginWidgetState();
  }
}

class LoginWidgetState extends State<LoginWidget> {
@override
  Widget build(BuildContext context) {
    //final _loginBloc = BlocProvider.of<LoginBloc>(context);
    const oneSec = const Duration(seconds: 1);
    //_loginBloc.add(ConnectivityResult.checkConnectivity());
    new Timer.periodic(oneSec, (Timer t) => Connectivity().checkConnectivity());
    return Scaffold(
        body: BlocProvider(
      builder: (BuildContext context) => LoginBloc(),
      child: new Form(
        key: _formKey,
        child: ListView(
          padding: EdgeInsets.only(top: 50.0),
          children: <Widget>[
            Image.asset(
              'assets/images/XXXXX_logo.jpg',
              height: 70,
              width: 100,
              alignment: Alignment.center,
            ),
            _buildTextFields(),
            _buildButtons(),
          ],
        ),
      ),
    ));
  }

  Widget _buildTextFields() {
    return new Container(
      padding: EdgeInsets.only(left: 16.0, right: 16.0),
      child: new Column(
        children: <Widget>[
          new Container(
            child: new TextFormField(
              controller: _userFilter,
              decoration: new InputDecoration(labelText: 'Username'),
              validator: (value) {
                if (value.isEmpty) {
                  return 'Username cannot be empty';
                }
                return null;
              },
            ),
          ),
          new Container(
            child: new TextFormField(
                controller: _passwordFilter,
                decoration: new InputDecoration(labelText: 'Password'),
                obscureText: true,
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Password cannot be empty';
                  }
                  return null;
                }),
          )
        ],
      ),
    );
  }

  Widget _buildButtons() {
    return new Container(
      child: new Column(
        children: <Widget>[
          new RaisedButton(
              child: new Text('Login'),
              onPressed: () {
                if (_formKey.currentState.validate()) {
                  _loginPressed();
                }
              }),
          new BlocBuilder<LoginBloc, bool>(
              builder: (BuildContext context, bool state) {
            return Container(
              color: state ? Colors.greenAccent : Colors.redAccent,
              padding: EdgeInsets.all(10.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new Text(
                    state ? "Connected" : "No Internet Connection",
                    textAlign: TextAlign.center,
                  )
                ],
              ),
            );
          }),
        ],
      ),
    );
  }

1 个答案:

答案 0 :(得分:2)

将调用函数mapEventToState的名称中所述,实际上是响应添加到Bloc接收器中的事件,然后您可以yield声明一个状态,发生这种情况时,BlocBuilder将在您的UI中收到该消息,因此,为了按预期工作,您应该创建一个事件,然后使用实例BlocProvider实例化您的Bloc并分派一个从那里发生的事件。

因此,根据您的代码

    final _loginBloc = BlocProvider.of<LoginBloc>(context);
    _loginBloc.add(YourEvent());

然后在mapEventToState

 Stream<bool> mapEventToState(LoginEvent event) async*{
    if (event is YourEvent) {
      yield YourState();
    }