Flutter-FlutterBloc的使用

BLOC說(shuō)明

bloc 是一個(gè)可預(yù)測(cè)的狀態(tài)管理庫(kù),有助于實(shí)現(xiàn) BLoC 設(shè)計(jì)模式。簡(jiǎn)單和輕便,高度可測(cè)試,適用于 Dart、Flutter 和 AngularDart。

簡(jiǎn)單使用

  1. 聲明自定義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;
}
  1. 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,
                )));
  }
}
  1. 在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í)者有所幫助。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容