BLOC說(shuō)明
bloc 是一個(gè)可預(yù)測(cè)的狀態(tài)管理庫(kù),有助于實(shí)現(xiàn) BLoC 設(shè)計(jì)模式。簡(jiǎn)單和輕便,高度可測(cè)試,適用于 Dart、Flutter 和 AngularDart。
簡(jiǎn)單使用
- 聲明自定義bloc類,繼承于Bloc, 然后添加相應(yīng)的事件對(duì)象和狀態(tài)的處理(通過(guò)emit把新的狀態(tài)反饋出去),如下:
/// APP全局Bloc類
class AppGlobalBloc extends Bloc<_AppGlobalEvent, AppGlobalState> {
AppGlobalBloc(super.initialState) {
// 下面在注冊(cè)相應(yīng)的事件,并在事件接收后變更狀態(tài)
on<_AppGlobalChangeThemeColorEvent>(
(event, emit) => emit(state.copyWith(themeColor: event.themeColor)));
on<_AppGlobalChangeUserNameEvent>(
(event, emit) => emit(state.copyWith(userName: event.userName)));
}
/// 變更主題色,就是添加一個(gè)變更主題色的事件
void changeThemeColor(MaterialColor themeColor) =>
add(_AppGlobalChangeThemeColorEvent(themeColor: themeColor));
/// 變更用戶名,就是添加一個(gè)變更用戶名的事件
void changeUserName(String? userName) =>
add(_AppGlobalChangeUserNameEvent(userName: userName));
}
/// 全局狀態(tài)類
class AppGlobalState {
AppGlobalState({
this.themeColor = Colors.indigo,
this.userName = "醬醬紫",
});
/// 主題色
MaterialColor themeColor;
/// 用戶名稱
String userName;
AppGlobalState copyWith({MaterialColor? themeColor, String? userName}) =>
AppGlobalState()
..themeColor = themeColor ?? this.themeColor
..userName = userName ?? this.userName;
static const List<MaterialColor> themeColors = Colors.primaries;
}
abstract class _AppGlobalEvent {}
class _AppGlobalChangeThemeColorEvent extends _AppGlobalEvent {
_AppGlobalChangeThemeColorEvent({this.themeColor});
MaterialColor? themeColor;
}
class _AppGlobalChangeUserNameEvent extends _AppGlobalEvent {
_AppGlobalChangeUserNameEvent({this.userName});
String? userName;
}
- main.dart中處理的Application的主題變更監(jiān)聽(tīng)
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(Application());
if (Platform.isAndroid) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(statusBarColor: Colors.transparent));
}
}
class Application extends StatelessWidget {
Application({super.key});
final GoRouter _router = GoRouter(routes: [
GoRoute(
path: '/',
pageBuilder: (_, __) =>
const CupertinoPage(child: HomePage(title: "首頁(yè)"))),
]);
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (_) => AppGlobalBloc(AppGlobalState())), //全局Bloc對(duì)象
],
child: BlocBuilder<AppGlobalBloc, AppGlobalState>(
builder: (_, state) => MaterialApp.router(
title: 'Flutter',
theme: ThemeData(primarySwatch: state.themeColor),
routerDelegate: _router.routerDelegate,
routeInformationParser: _router.routeInformationParser,
routeInformationProvider: _router.routeInformationProvider,
)));
}
}
-
在HomePage中處理主題色變更,先看一下UI效果圖,如下
效果圖
說(shuō)明:通過(guò)點(diǎn)擊上圖中的顏色框,可以更改主題顏色,Bloc狀態(tài)通知到位!
class HomePage extends StatefulWidget {
const HomePage({super.key, required this.title});
final String title;
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final HomePageBloc _bloc = HomePageBloc(HomePageState());
@override
void initState() {
_bloc.init();
super.initState();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
appBar: AppBar(centerTitle: true, title: Text(widget.title)),
body: BlocBuilder<HomePageBloc, HomePageState>(
bloc: _bloc,
builder: (ctx, state) => _buildContentView(state),
),
floatingActionButton: FloatingActionButton(
mini: true,
tooltip: 'Increment',
onPressed: _bloc.incrementCounter,
child: const Icon(Icons.add)),
floatingActionButtonLocation: FloatingActionButtonLocation.endTop,
),
onWillPop: () async => true);
}
Widget _buildContentView(HomePageState state) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Padding(
padding: EdgeInsets.only(top: 12, left: 12),
child: Text("主題顏色設(shè)置")),
Padding(
padding: const EdgeInsets.all(12),
child: Wrap(spacing: 12, runSpacing: 12, children: [
for (MaterialColor color in AppGlobalState.themeColors)
SizedBox(
width: 40,
height: 40,
child: InkWell(
onTap: () => context
.read<AppGlobalBloc>()
.changeThemeColor(color), //調(diào)用Bloc變更主題顏色的方法
child:
Container(width: 40, height: 40, color: color)))
])),
_buildItemView(title: "劉大能", address: "重慶渝中區(qū)大溪溝", phoneNumber: "132*****629"),
]);
}
Widget _buildItemView({String? title, String? address, String? phoneNumber}) {
return Card(
margin: const EdgeInsets.all(12.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text("${title ?? ""} ${phoneNumber ?? ""}",
style:
const TextStyle(fontSize: 16, color: Colors.indigo)),
const Divider(height: 8, color: Colors.transparent),
Text("地址:${address ?? ""}",
style: const TextStyle(color: Colors.black38))
])
],
)));
}
}
這里是Bloc的一個(gè)簡(jiǎn)單實(shí)用案例,希望對(duì)各位Bloc的學(xué)習(xí)者有所幫助。
