【问题标题】:Listen to Events instead of States with Flutter BLOC使用 Flutter BLOC 监听事件而不是状态
【发布时间】:2020-04-29 02:57:12
【问题描述】:

我正在使用 Flutter BLOC 库 (https://pub.dev/packages/bloc) 我知道有一种方法可以“监听” BLOC 状态变化(使用 listen() 函数)

chatBloc.listen((chatState) async {
      if (chatState is ChatStateInitialized) {
        // do something
      }
    });

但是有没有办法代替监听 BLOC 事件?就像我对经典 StreamController 所做的那样? 感谢所有愿意提供帮助的人:-)

朱利安

【问题讨论】:

    标签: flutter bloc flutter-bloc


    【解决方案1】:

    更新至版本 7/8

    聆听集团的变化

    如果您只需要监听一个 Bloc 更改,您可以在所需的 Bloc 类中覆盖 void onChange(Change<State> change)

    enum CounterEvent { increment }
    
    class CounterBloc extends Bloc<CounterEvent, int> {
      CounterBloc() : super(0);
    
      @override
      Stream<int> mapEventToState(CounterEvent event) async* {
        switch (event) {
          case CounterEvent.increment:
            yield state + 1;
            break;
        }
      }
    
      @override
      void onChange(Change<int> change) {
        print(change);
        super.onChange(change);
      }
    }
    

    聆听多个集团变化

    如果您需要在多个 Bloc 上全局监听更改,可以使用 BlocObserver 类。

    class SimpleBlocObserver extends BlocObserver {
      @override
      void onChange(BlocBase bloc, Change change) {
        super.onChange(bloc, change);
        print('${bloc.runtimeType} $change');
      }
    
      @override
      void onTransition(Bloc bloc, Transition transition) {
        super.onTransition(bloc, transition);
        print('${bloc.runtimeType} $transition');
      }
    
      @override
      void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
        print('${bloc.runtimeType} $error $stackTrace');
        super.onError(bloc, error, stackTrace);
      }
    }
    

    然后,你需要初始化它。

    void main() {
      Bloc.observer = SimpleBlocObserver();
      CounterBloc()
        ..add(CounterEvent.increment)
        ..close();
    }
    

    有关Flutter Bloc library documentation的更多信息。

    【讨论】:

      【解决方案2】:

      是的,您可以通过以下代码监听 BLoC 事件:

      BlocSupervisor.delegate = MyBlocDelegate();
      

      而你的 ma​​in.dart 类似于下面的代码:

      void main() {
        WidgetsFlutterBinding.ensureInitialized();
        BlocSupervisor.delegate = MyBlocDelegate();
        runApp(MyApp());
      }
      
      class MyApp extends StatelessWidget {
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: BlocProvider<CounterBLoC>(
              create: (ctx) => CounterBLoC(),
              child: TestBlocWidget(),
            ),
          );
        }
      }
      

      这是您的 bloc_delegate.dart,用于收听 BLoC 的事件:

      import 'package:bloc/bloc.dart';
      
      class MyBlocDelegate extends BlocDelegate {
        @override
        void onEvent(Bloc bloc, Object event) {
          print(event);
          super.onEvent(bloc, event);
        }
      
        @override
        void onError(Bloc bloc, Object error, StackTrace stackTrace) {
          print(error);
          super.onError(bloc, error, stackTrace);
        }
      
        @override
        void onTransition(Bloc bloc, Transition transition) {
          print(transition);
          super.onTransition(bloc, transition);
        }
      }
      

      【讨论】:

      • 谢谢塔勒布。我也能够通过新的 BlocConsumer 实现这一目标
      猜你喜欢
      • 2021-02-17
      • 2020-03-26
      • 2022-10-23
      • 2020-02-18
      • 2020-03-27
      • 2020-06-15
      • 2022-10-06
      • 2019-11-26
      • 2021-02-20
      相关资源
      最近更新 更多