Ados

a fullstack game worker

0%

每天进步一点点026 - Flutter状态管理之BLoC

Preface

本来Flutter状态管理用一篇来写完的,但是看起来有点长,所以分开来记录。

BLoC,Bussiness Logic Component,业务逻辑组件,参考1里面就是它的原理和介绍。

在pub.dev上我们可以看到两个bloc相关的包,一个是bloc,一个是flutter_bloc。前者是bloc的dart基本实现,后者是针对flutter的整合。所以,直接用后者就可以了。

Contents

Hello BLoC

以下几步就可以简单的将BLoC导入咱们的hello world计数器项目。

自定义 Cubit

1
2
3
4
5
6
7
import 'package:flutter_bloc/flutter_bloc.dart';

class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void decrement() => emit(state - 1);
}

咱们的CounterCubit继承的Cubit,Cubit其实只是一个抽象类,继承了BlocBase:

1
2
3
abstract class Cubit<State> extends BlocBase<State> {
Cubit(State initialState) : super(initialState);
}

所以,核心还是在BlocBase:

1
2
abstract class BlocBase<State>
implements StateStreamableSource<State>, Emittable<State>, ErrorSink

BlocBase就两个实现,一个是上面的Cubit,一个是Bloc

使用BlocBuilder进行build

BlocBuilder是一个flutter widget,需要一个 bloc和一个 builder函数。

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
// 注意,此处咱们不用StatefulWidget
class CounterCubitPage extends StatelessWidget {
const CounterCubitPage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Bloc Cubit Test"),
),
body: BlocBuilder<CounterCubit, int>(
builder: (context, count) => Center(
child: Text("$count"),
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => context.read<CounterCubit>().increment(),
),
const SizedBox(
height: 4,
),
FloatingActionButton(
child: const Icon(Icons.remove),
onPressed: () => context.read<CounterCubit>().decrement(),
heroTag: "remove",
),
],
),
);
}
}

MultiBlocProvider

如果会用到多个BLoC的时候,可以使用MultiBlocProvider进行整合。

from:

1
2
3
4
5
6
7
8
9
10
BlocProvider<BlocA>(
create: (BuildContext context) => BlocA(),
child: BlocProvider<BlocB>(
create: (BuildContext context) => BlocB(),
child: BlocProvider<BlocC>(
create: (BuildContext context) => BlocC(),
child: ChildA(),
)
)
)

to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ultiBlocProvider(
providers: [
BlocProvider<BlocA>(
create: (BuildContext context) => BlocA(),
),
BlocProvider<BlocB>(
create: (BuildContext context) => BlocB(),
),
BlocProvider<BlocC>(
create: (BuildContext context) => BlocC(),
),
],
child: ChildA(),
)

Reference

  1. 响应式编程-流-bloc
  2. bloc