本节目标
为什么要用 bloc
bloc vs provider
学习路线推荐
安装 bloc vscode 插件
配置 bloc 依赖包
编写计算器示例
视频 https://www.bilibili.com/video/BV1ef4y1e79o/
代码 https://github.com/ducafecat/flutter-bloc-learn/tree/master/ducafecat_bloc_start_example
正文 为什么要用 bloc
状态管理(这是必须的)
三层分离
表现层(Presentation)
业务逻辑(Business Logic)
数据层(Data)
数据源/库(Repository)
数据提供者(Data Provider)
规范组内开发
方便的 测试、记录 用户行为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class SimpleBlocDelegate extends BlocDelegate { @override void onEvent(Bloc bloc, Object event) { super .onEvent(bloc, event); print ('${bloc.runtimeType} $event ' ); } @override void onError(Bloc bloc, Object error, StackTrace stacktrace) { super .onError(bloc, error, stacktrace); print ('${bloc.runtimeType} $error ' ); } @override void onTransition(Bloc bloc, Transition transition) { super .onTransition(bloc, transition); print (transition); } }
bloc vs provider
bloc 学习路线
安装 bloc vscode 插件 bloc
创建项目
1 2 3 4 5 6 7 8 name: ducafecat_bloc_start_example ... dependencies: ... bloc: ^6.1.0 flutter_bloc: ^6.1.0 equatable: ^1.2.5
counter 计算器业务下创建 bloc view 目录,这样就分离了
编写 bloc
lib/counter/bloc/counter_bloc.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import 'dart:async' ;import 'package:bloc/bloc.dart' ;import 'package:equatable/equatable.dart' ;import 'package:meta/meta.dart' ;part 'counter_event.dart' ;part 'counter_state.dart' ;class CounterBloc extends Bloc <CounterEvent , CounterState > { CounterBloc() : super (CounterInitial(0 )); int counterNum = 0 ; @override Stream<CounterState> mapEventToState( CounterEvent event, ) async * { if (event is CounterIncrement) { yield * _mapIncrementEventToState(event); } else if (event is CounterSubduction) { yield * _mapSubductionEventToState(event); } } Stream<CounterState> _mapIncrementEventToState( CounterIncrement event) async * { this .counterNum += 1 ; yield CounterChange(this .counterNum); } Stream<CounterState> _mapSubductionEventToState( CounterSubduction event) async * { this .counterNum -= 1 ; yield CounterChange(this .counterNum); } }
lib/counter/bloc/counter_event.dart
1 2 3 4 5 6 7 8 9 10 11 part of 'counter_bloc.dart' ;@immutable abstract class CounterEvent extends Equatable { @override List <Object > get props => []; } class CounterIncrement extends CounterEvent {}class CounterSubduction extends CounterEvent {}
lib/counter/bloc/counter_state.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 part of 'counter_bloc.dart' ;@immutable abstract class CounterState extends Equatable { final int value; const CounterState(this .value); @override List <Object > get props => [value]; } class CounterInitial extends CounterState { CounterInitial(int value) : super (value); } class CounterChange extends CounterState { CounterChange(int value) : super (value); }
编写 view
lib/counter/view/page.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import 'package:ducafecat_bloc_start_example/counter/bloc/counter_bloc.dart' ;import 'package:ducafecat_bloc_start_example/counter/view/view.dart' ;import 'package:flutter/material.dart' ;import 'package:flutter_bloc/flutter_bloc.dart' ;class CounterPage extends StatelessWidget { const CounterPage({Key key}) : super (key: key); @override Widget build(BuildContext context) { return BlocProvider( create: (context) => CounterBloc(), child: CounterView(), ); } }
lib/counter/view/view.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import 'package:ducafecat_bloc_start_example/counter/bloc/counter_bloc.dart' ;import 'package:flutter/material.dart' ;import 'package:flutter_bloc/flutter_bloc.dart' ;class CounterView extends StatelessWidget { const CounterView({Key key}) : super (key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Counter' )), body: Center( child: Column( children: [ BlocBuilder<CounterBloc, CounterState>( builder: (context, state) { return Text('${state.value} ' ); }, ), RaisedButton( child: Text('加法' ), onPressed: () { BlocProvider.of<CounterBloc>(context).add(CounterIncrement()); }, ), RaisedButton( child: Text('加法' ), onPressed: () { BlocProvider.of<CounterBloc>(context).add(CounterSubduction()); }, ) ], ), ), ); } }
1 2 3 4 5 6 7 8 9 10 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( ... home: CounterPage(), ); } }
参考
© 猫哥
https://ducafecat.tech
https://ducafecat.gitee.io
邮箱 ducafecat@gmail.com / 微信 ducafecat / 留言板 disqus