美文网首页Flutter圈子
Flutter-FlutterBloc的使用

Flutter-FlutterBloc的使用

作者: Cosecant | 来源:发表于2022-09-22 10:23 被阅读0次

    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的学习者有所帮助。

    相关文章

      网友评论

        本文标题:Flutter-FlutterBloc的使用

        本文链接:https://www.haomeiwen.com/subject/anyqortx.html