首先,有很多的文章在说flutter bloc模式的应用,但是百分之八九十的文章都是在说,使用StreamController+StreamBuilder搭建bloc,提升性能的会加上InheritedWidget,这些文章看了很多,真正写使用bloc作者开发的flutter_bloc却少之又少。没办法,只能去bloc的github上去找使用方式,最后去bloc官网翻文档。
蛋痛,各位叼毛,就不能好好说说flutter_bloc的使用吗?非要各种抄bloc模式提出作者的那俩篇文章。现在,搞的杂家这个伸手党要自己去翻文档总结(手动滑稽)。
来来,伸手党们,赶紧保存下面的链接
flutter_bloc: ^6.0.1 #状态管理框架
equatable: ^1.2.3 #增强组件相等性判断
在Android Studio设置的Plugins里,搜索:Bloc
安装重启下,就OK了
来看下这三个生成的bloc文件:main_bloc,main_event,main_state
class MainBloc extends Bloc<MainEvent, MainState> {
MainBloc() : super(MainInitial());
@override
Stream<MainState> mapEventToState(
MainEvent event,
) async* {
// TODO: implement mapEventToState
}
}
@immutable
abstract class MainEvent {}
@immutable
abstract class MainState {}
class MainInitial extends MainState {}
class MainBloc extends Bloc<MainEvent, MainState> {
MainBloc() : super(MainState(selectedIndex: 0, isExtended: false));
@override
Stream<MainState> mapEventToState(MainEvent event) async* {
///main_view中添加的事件,会在此处回调,此处处理完数据,将数据yield,BlocBuilder就会刷新组件
if (event is SwitchTabEvent) {
///获取到event事件传递过来的值,咱们拿到这值塞进MainState中
///直接在state上改变内部的值,然后yield,只能触发一次BlocBuilder,它内部会比较上次MainState对象,如果相同,就不build
yield MainState()
..selectedIndex = event.selectedIndex
..isExtended = state.isExtended;
} else if (event is IsExtendEvent) {
yield MainState()
..selectedIndex = state.selectedIndex
..isExtended = !state.isExtended;
}
}
}
@immutable
abstract class MainEvent extends Equatable{
const MainEvent();
}
///切换NavigationRail的tab
class SwitchTabEvent extends MainEvent{
final int selectedIndex;
const SwitchTabEvent({@required this.selectedIndex});
@override
List<Object> get props => [selectedIndex];
}
///展开NavigationRail,这个逻辑比较简单,就不用传参数了
class IsExtendEvent extends MainEvent{
const IsExtendEvent();
@override
List<Object> get props => [];
}
class MainState{
int selectedIndex;
bool isExtended;
MainState({this.selectedIndex, this.isExtended});
}
@immutable
abstract class LoadingState extends Equatable {}
class LoadingInitial extends LoadingState {
@override
List<Object> get props => [];
}
class LoadingBeforeSate extends LoadingState{
///实现相应的字段信息
@override
List<Object> get props => [];
}
class LoadingFailureState extends LoadingState{
///实现相应的字段信息
@override
List<Object> get props => [];
}
class LoadingSuccessState extends LoadingState{
///实现相应的字段信息
@override
List<Object> get props => [];
}
///在View中使用,伪代码
BlocBuilder<MainBloc, MainState>(builder: (context, state) {
if(state is LoadingBeforeSate){
return Beforewidget(state.XX,..);
} else if(state is LoadingFailureState){
return FailureWidget(state.XX,state.XX,...);
} else if(state is LoadingSuccessState){
return SuccessWidget(state.XX);
} else {
return ErrorWidget(...);
}
})
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainPage(),
);
}
}
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
///创建BlocProvider的,表明该Page,我们是用MainBloc,MainBloc是属于该页面的Bloc了
return BlocProvider(
create: (BuildContext context) => MainBloc(),
child: BodyPage(),
);
}
}
class BodyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Bloc')),
body: totalPage(),
);
}
}
Widget totalPage() {
return Row(
children: [
navigationRailSide(),
Expanded(child: Center(
child: BlocBuilder<MainBloc, MainState>(builder: (context, state) {
///看这看这:刷新组件!
return Text("selectedIndex:" + state.selectedIndex.toString());
}),
))
],
);
}
//增加NavigationRail组件为侧边栏
Widget navigationRailSide() {
//顶部widget
Widget topWidget = Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 80,
height: 80,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3383029432,2292503864&fm=26&gp=0.jpg"),
fit: BoxFit.fill),
)),
),
);
//底部widget
Widget bottomWidget = Container(
child: BlocBuilder<MainBloc, MainState>(
builder: (context, state) {
return FloatingActionButton(
onPressed: () {
///添加NavigationRail展开,收缩事件
context.bloc<MainBloc>().add(IsExtendEvent());
},
///看这看这:刷新组件!
child: Icon(state.isExtended ? Icons.send : Icons.navigation),
);
},
),
);
return BlocBuilder<MainBloc, MainState>(builder: (context, state) {
return NavigationRail(
backgroundColor: Colors.white12,
elevation: 3,
///看这看这:刷新组件!
extended: state.isExtended,
labelType: state.isExtended ? NavigationRailLabelType.none : NavigationRailLabelType.selected,
//侧边栏中的item
destinations: [
NavigationRailDestination(
icon: Icon(Icons.add_to_queue),
selectedIcon: Icon(Icons.add_to_photos),
label: Text("测试一")),
NavigationRailDestination(
icon: Icon(Icons.add_circle_outline),
selectedIcon: Icon(Icons.add_circle),
label: Text("测试二")),
NavigationRailDestination(
icon: Icon(Icons.bubble_chart),
selectedIcon: Icon(Icons.broken_image),
label: Text("测试三")),
],
//顶部widget
leading: topWidget,
//底部widget
trailing: bottomWidget,
selectedIndex: state.selectedIndex,
onDestinationSelected: (int index) {
///添加切换tab事件
context.bloc<MainBloc>().add(SwitchTabEvent(selectedIndex: index));
},
);
});
}