数据传递
- Provider:通过依赖注入方式在Widget树中传递数据。例如,创建一个
ChangeNotifierProvider
包裹需要数据的子树,子树内的Widget可以通过Provider.of
获取数据。示例:
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Counter(),
child: MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Consumer<Counter>(
builder: (context, counter, child) {
return Text('Count: ${counter.count}');
},
),
RaisedButton(
child: Text('Increment'),
onPressed: () {
Provider.of<Counter>(context, listen: false).increment();
},
)
],
),
),
),
),
);
}
}
- Bloc:通过事件流(Event Stream)传递数据。Bloc监听事件,处理后发出新的状态。例如,创建一个
CounterBloc
,监听IncrementEvent
并发出新的CounterState
。示例:
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
abstract class CounterState {}
class InitialCounterState extends CounterState {}
class UpdatedCounterState extends CounterState {
final int count;
UpdatedCounterState(this.count);
}
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(InitialCounterState());
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
if (event is IncrementEvent) {
if (state is InitialCounterState) {
yield UpdatedCounterState(1);
} else if (state is UpdatedCounterState) {
yield UpdatedCounterState((state as UpdatedCounterState).count + 1);
}
}
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CounterBloc(),
child: MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
if (state is InitialCounterState) {
return Text('Count: 0');
} else if (state is UpdatedCounterState) {
return Text('Count: ${(state as UpdatedCounterState).count}');
}
return Container();
},
),
RaisedButton(
child: Text('Increment'),
onPressed: () {
BlocProvider.of<CounterBloc>(context).add(IncrementEvent());
},
)
],
),
),
),
),
);
}
}
事件处理
- Provider:通常在Widget中直接调用数据提供者的方法来处理事件。例如在上述Provider示例中,
RaisedButton
的onPressed
直接调用Counter
的increment
方法。
- Bloc:通过向Bloc发送事件(
add
方法),Bloc内部的mapEventToState
方法来处理事件并发出新状态。如上述Bloc示例中,RaisedButton
的onPressed
调用BlocProvider.of<CounterBloc>(context).add(IncrementEvent())
。
适用场景
- Provider:适用于简单的状态管理场景,尤其是数据传递和更新逻辑较为直接的情况。比如一个简单的计数器应用,或者在Widget树中共享一些配置数据等。
- Bloc:适用于复杂的业务逻辑和状态管理场景,特别是当事件驱动的架构更合适时。例如在电商应用中,处理商品添加到购物车、下单等一系列复杂操作及状态变化。