【问题标题】:Flutter Bloc - BlocListener not reacting to state changeFlutter Bloc - BlocListener 对状态变化没有反应
【发布时间】:2021-04-17 04:33:09
【问题描述】:

我的应用程序的想法是用户能够添加休假约会。添加新的休假约会后,用户会收到通知消息。为了实现这一点,我有一个休息时间,它对 AddTimeOffEvent 做出反应并设置两个状态 TimeOffAddingState 和 TimeOffAddedState。我正在使用 flutter_bloc 库。

我的集团:

class TimeOffBloc extends Bloc<TimeOffEvent, TimeOffState> {
  TimeOffRepository repository;
  String activeUser;

  TimeOffBloc({@required this.repository}) : super(TimeOffInitialState());

  @override
  Stream<TimeOffState> mapEventToState(TimeOffEvent event) async* {
    if (event is AddTimeOffEvent) {
      yield TimeOffAddingState();
      try {
        var addResult = await repository.addTimeOff(event.timeOff, activeUser);
        TimeOffsRange timeOffsRange =
            await repository.fetchTimeOffRange(activeUser);
        yield TimeOffAddedState(
            timeOffs: timeOffsRange, excludedWeekends: addResult);
      } catch (e) {
        yield TimeOffErrorState(message: e.toString());
      }
    }
  }
}

我的活动:

abstract class TimeOffEvent extends Equatable {}

class AddTimeOffEvent extends TimeOffEvent {
  final AddTimeOff timeOff;

  AddTimeOffEvent({@required this.timeOff});

  List<Object> get props => [timeOff];
}

我的状态:

abstract class TimeOffState extends Equatable {}

class TimeOffInitialState extends TimeOffState {
  String message = "Loading";

  @override
  List<Object> get props => [];
}

class TimeOffAddedState extends TimeOffState {
  TimeOffsRange timeOffs;
  String excludedWeekends;

  TimeOffAddedState({@required this.timeOffs, this.excludedWeekends});

  List<Object> get props => [timeOffs, excludedWeekends];
}

class TimeOffAddingState extends TimeOffState {
  String message = "Adding new time off appointments.";

  @override
  List<Object> get props => [message];
}

class TimeOffErrorState extends TimeOffState {
  String message;

  TimeOffErrorState({@required this.message});

  @override
  List<Object> get props => [message];
}

集团建设者

在 bloc builder 小部件中检测到从 TimeOffAddingState 到 TimeOffAddedState 的状态变化。

class _TimeOffListContainerState extends State<TimeOffListContainer> {
  TimeOffBloc timeOffBloc;

  @override
  void initState() {
    super.initState();
    timeOffBloc = BlocProvider.of<TimeOffBloc>(context);
  }

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: () => getTimeOffs(),
      child: BlocBuilder<TimeOffBloc, TimeOffState>(
        builder: (context, state) {
          if (state is TimeOffInitialState) {
            return Loading(loadingMessage: state.message);
          } else if (state is TimeOffAddingState) {
            return Loading(loadingMessage: state.message);
          } else if (state is TimeOffAddedState) {
            return TimeOffList(
                timeOffs: state.timeOffs, timeOffBloc: timeOffBloc);
          } else if (state is TimeOffErrorState) {
            return Error(
              errorMessage: state.message,
              onRetryPressed: () => getTimeOffs(),
            );
          }
        },
      ),
    );
  }
}

我有一个 timeOffListPage,用于显示约会时间。页面上有一个 Bloc Listener,它应该在 TimeOffAddesState 上显示一条消息。但这不起作用。在调试过程中,我发现在设置 TimeOffAddingState 时调用了 BlocListener。但是 TimeOffAddedState 被忽略。令人困惑的是,当我没有在 bloc 上产生 TimeOffAddingState 时,bloc 侦听器适用于 TimeOffAddedState。

    final TimeOffsRange timeOffs;
  final TimeOffBloc timeOffBloc;

  const TimeOffList({Key key, this.timeOffs, this.timeOffBloc})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocListener<TimeOffBloc, TimeOffState>(
      listener: (context, state) {
        if (state is TimeOffAddedState) { //is never called...
          if (state.excludedWeekends.isNotEmpty) {
            showSimpleNotification(
              Text(state.excludedWeekends),
              background: Colors.amber,
              duration: Duration(milliseconds: 10000),
            );
          }
        }
      },
      child: Scaffold(...

有什么想法吗?

【问题讨论】:

    标签: android flutter bloc


    【解决方案1】:

    请查看下面的代码,我在插入新代码行的位置添加了 cmets。让我知道它是否对您有帮助。

    我的集团:

    class TimeOffBloc extends Bloc<TimeOffEvent, TimeOffState> {
      TimeOffRepository repository;
      String activeUser;
    
      TimeOffBloc({@required this.repository}) : super(TimeOffInitialState());
    
      @override
      Stream<TimeOffState> mapEventToState(TimeOffEvent event) async* {
        if (event is AddTimeOffEvent) {
          yield TimeOffAddingState();
          try {
            var addResult = await repository.addTimeOff(event.timeOff, activeUser);
            TimeOffsRange timeOffsRange =
                await repository.fetchTimeOffRange(activeUser);
            //add this line of code
            yield TimeOffIdleState();
            await Future.delayed(duration: Duration(milliseconds : 20));
            yield TimeOffAddedState(
                timeOffs: timeOffsRange, excludedWeekends: addResult);
          } catch (e) {
            //add this line of code
            yield TimeOffIdleState();
            await Future.delayed(duration: Duration(milliseconds : 20));
            yield TimeOffErrorState(message: e.toString());
          }
        }
      }
    }
    

    我的活动:

    abstract class TimeOffEvent extends Equatable {}
    
    class AddTimeOffEvent extends TimeOffEvent {
      final AddTimeOff timeOff;
    
      AddTimeOffEvent({@required this.timeOff});
    
      List<Object> get props => [timeOff];
    }
    

    我的状态:

    abstract class TimeOffState extends Equatable {}
    
    class TimeOffInitialState extends TimeOffState {
      String message = "Loading";
    
      @override
      List<Object> get props => [];
    }
    
    class TimeOffAddedState extends TimeOffState {
      TimeOffsRange timeOffs;
      String excludedWeekends;
    
      TimeOffAddedState({@required this.timeOffs, this.excludedWeekends});
    
      List<Object> get props => [timeOffs, excludedWeekends];
    }
    
    class TimeOffAddingState extends TimeOffState {
      String message = "Adding new time off appointments.";
    
      @override
      List<Object> get props => [message];
    }
    
    class TimeOffErrorState extends TimeOffState {
      String message;
    
      TimeOffErrorState({@required this.message});
    
      @override
      List<Object> get props => [message];
    }
    //add this class
    class TimeOffIdleState extends TimeOffState {
      @override
      List<Object> get props => [];
    }
    

    集团建设者

    在 bloc builder 小部件中检测到从 TimeOffAddingState 到 TimeOffAddedState 的状态变化。

    class _TimeOffListContainerState extends State<TimeOffListContainer> {
      TimeOffBloc timeOffBloc;
    
      @override
      void initState() {
        super.initState();
        timeOffBloc = BlocProvider.of<TimeOffBloc>(context);
      }
    
      @override
      Widget build(BuildContext context) {
        return RefreshIndicator(
          onRefresh: () => getTimeOffs(),
          child: BlocBuilder<TimeOffBloc, TimeOffState>(
            builder: (context, state) {
              if (state is TimeOffInitialState) {
                return Loading(loadingMessage: state.message);
              } else if (state is TimeOffAddingState) {
                return Loading(loadingMessage: state.message);
              } else if (state is TimeOffAddedState) {
                return TimeOffList(
                    timeOffs: state.timeOffs, timeOffBloc: timeOffBloc);
              }
                //add this line of code, you can return any widget at all
                else if (state is TimeOffIdleState){return Container();}
                else if (state is TimeOffErrorState) {
                return Error(
                  errorMessage: state.message,
                  onRetryPressed: () => getTimeOffs(),
                );
              }
            },
          ),
        );
      }
    }
    

    【讨论】:

    • 方法 mapEventToState 需要 Stream 类型的返回值。我不能让出另一个状态。我错过了什么吗? Stream&lt;TimeOffState&gt; mapEventToState(TimeOffEvent event) async* {...} 但我可以使用 BlocBuilder 小部件捕获所有状态。 BlocBuilder&lt;TimeOffBloc, TimeOffState&gt;(builder: (context, state) {}
    • 在这种情况下,您必须从您的事件、状态、块类中发布代码。否则不清楚解决问题。
    • 我在最初的帖子中添加了更多细节。您可以看到我的 bloc 和 bloc builder 小部件,其中检测到从 TimeOffAddingState 到 TimeOffAddedState 的状态变化。
    • 太好了,我正在编辑答案。请在我更新答案时查看它
    • 我已经编辑了答案,请看一下,如果对您有帮助,请告诉我。
    猜你喜欢
    • 2022-07-22
    • 2021-02-12
    • 2021-04-14
    • 1970-01-01
    • 2021-10-31
    • 2022-06-21
    • 2021-03-19
    • 2021-02-17
    • 2020-05-06
    相关资源
    最近更新 更多