Flutter圈子

Flutter-FlutterBloc的使用

2022-09-22  本文已影响0人  Cosecant

BLOC说明

bloc 是一个可预测的状态管理库,有助于实现 BLoC 设计模式。简单和轻便,高度可测试,适用于 Dart、Flutter 和 AngularDart。

简单使用

  1. 声明自定义bloc类,继承于Bloc, 然后添加相应的事件对象和状态的处理(通过emit把新的状态反馈出去),如下:
/// APP全局Bloc类
class AppGlobalBloc extends Bloc<_AppGlobalEvent, AppGlobalState> {
  AppGlobalBloc(super.initialState) {
    // 下面在注册相应的事件,并在事件接收后变更状态
    on<_AppGlobalChangeThemeColorEvent>(
        (event, emit) => emit(state.copyWith(themeColor: event.themeColor)));
    on<_AppGlobalChangeUserNameEvent>(
        (event, emit) => emit(state.copyWith(userName: event.userName)));
  }

  /// 变更主题色,就是添加一个变更主题色的事件
  void changeThemeColor(MaterialColor themeColor) =>
      add(_AppGlobalChangeThemeColorEvent(themeColor: themeColor));

/// 变更用户名,就是添加一个变更用户名的事件
  void changeUserName(String? userName) =>
      add(_AppGlobalChangeUserNameEvent(userName: userName));
}

/// 全局状态类
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的主题变更监听
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: "首页"))),
  ]);

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
        providers: [
          BlocProvider(create: (_) => AppGlobalBloc(AppGlobalState())), //全局Bloc对象
        ],
        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效果图,如下


    效果图

    说明:通过点击上图中的颜色框,可以更改主题颜色,Bloc状态通知到位!

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("主题颜色设置")),
          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), //调用Bloc变更主题颜色的方法
                          child:
                              Container(width: 40, height: 40, color: color)))
              ])),
          _buildItemView(title: "刘大能", address: "重庆渝中区大溪沟", 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的一个简单实用案例,希望对各位Bloc的学习者有所帮助。

上一篇 下一篇

猜你喜欢

热点阅读