我正在使用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,
)
],
),
);
}),
],
),
);
}
答案 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();
}