要确保 BlocBuilder 或 BlocProvider 的状态是在 BlocListener 中更新的,否则 BlocListener 将始终接收到初始加载状态。解决方法是在需要更新状态的 BlocBuilder 或 BlocProvider 中使用一个新变量来存储当前状态,并在需要更新状态时使用一个新的方法来更新该变量。
例如,假设我们有一个 CounterBloc,它会根据用户操作更新状态。我们可以使用以下代码来解决该问题:
class CounterBloc extends Bloc {
CounterBloc() : super(0);
@override
Stream mapEventToState(CounterEvent event) async* {
if (event == CounterEvent.increment) {
yield state + 1;
} else if (event == CounterEvent.decrement) {
yield state - 1;
}
}
}
class CounterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CounterBloc(),
child: BlocBuilder(
builder: (context, state) {
return Text('$state');
},
),
);
}
}
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Counter'),
),
body: BlocListener(
listener: (context, state) {
print('Counter state changed to $state');
},
child: CounterWidget(),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () =>
context.read().add(CounterEvent.increment),
child: Icon(Icons.add),
),
SizedBox(height: 8),
FloatingActionButton(
onPressed: () =>
context.read().add(CounterEvent.decrement),
child: Icon(Icons.remove),
),
],
),
);
}
}
在这个例子中,我们使用 BlocProvider
和 BlocBuilder
来创建并显示计数器的当前值。在 CounterPage
中使用 BlocListener
来监听计数器的状态变化。
要确保 BlocListener
正确更新状态,我们必须在 CounterBloc
中使用 yield
来更新状态,并在 BlocBuilder
中使用一个新的变量来存储当前值。然后在 BlocListener
中监听该变量的变化,而不是 CounterBloc
直接返回的值。
使用这种方法,我们