代码之家  ›  专栏  ›  技术社区  ›  Ben

flutter block:如何创建和使用子类型状态

  •  0
  • Ben  · 技术社区  · 3 年前

    我试图在我的项目中使用flutter和block,但有一个关于状态的问题。

    我看到了一些为事件创建特定状态类的示例。例如

    abstract class TimerState extends Equalable {
       final int duration;
    
       TimerState({required this.duration});
    
       @override
      List<Object> get props => [
            duration
          ];
    
    }
    
    class InitialTimerState extends TimerState {}
    
    class TimerStartState extends TimerState {}
    
    class TimerStopState extends TimerState {}
    
    

    现在,我在基本状态类中有三个字段,例如

    abstract class TimerState extends Equalable {
       final int duration;
       final String message;
       final bool isStop;
    
       TimerState({this.duration = 10, this.message = '', this.isStop = false});
    
       @override
      List<Object> get props => [
            duration
          ];
    
    }
    
    class InitialTimerState extends TimerState {
      // how to set duration and message while keep isStop not changed?
    }
    
    class TimerStartState extends TimerState {
      // how to set isStop and message while keep duration not changed?
    }
    
    class TimerStopState extends TimerState {
      // how to set isStop and message while keep duration not changed?
    }
    

    我希望有集团式的

    on<InitialTimer>((event, emit) => emit(InitialTimerState()));
    on<TimerStart>((event, emit) => emit(TimerStartState()));
    on<TimerStop>((event, emit) => emit(TimerStopState()));
    

    我之所以要这样做,是因为我想在BlocConsumer中触发具有不同状态的侦听器

    listen: (ctx, state) {
      if (state is InitialTimerState) {
        // show dialog
      }
      else if (state is TimerStartState) {
        // show snacker
      }
    }
    listenWhen: (previous, current) {
      return current.message != previous.message
    }
    
    
    0 回复  |  直到 3 年前
        1
  •  0
  •   Ammar Hammoud    3 年前

    看看 dart documentation for classes ,您可以使用supervisor类的构造函数,因此当您想更改一个值时,将其和其他值作为 super.data ,我真的不确定语法,但你明白了,我认为应该是这样的:

    class TimerStates extends ..{
      //Declare variables
      final Duration duration;
      final String message;
      final bool isStop;
    
      //Named constructor
      TimerStates.init({
      required this.duration,
      required this.message,
      required this.isStop});
    
      //The rest of your code
    }
    
    class InitialTimerState extends TimerStates{
       final Duration duration;
       final String message;
       InitialTimerState({
          required this.duration,
          required this.message 
          }):super(
             duration: this.duration,
             message: this.message,
             isStop: super.isStop);
    }
    
        2
  •  0
  •   Vladyslav Ulianytskyi    3 年前

    如果您的TimerScreen将定期接收数据并显示更改(我的意思是,此屏幕不仅用于获取数据并显示一次),那么您的状态可能如下所示:

    class TimerState extends Equatable {
      const TimerState({
        this.duration = 10,
        this.message = '',
        this.isTicking = false,
      });
    
      final int duration;
      final String message;
      final bool isTicking;
    
      @override
      List<Object> get props => [
            duration,
            message,
            isTicking,
          ];
    
      TimerState copyWith({int? duration, String? message, bool? isTicking}) =>
          TimerState(
            duration: duration ?? this.duration,
            message: message ?? this.message,
            isTicking: isTicking ?? this.isTicking,
          );
    }
    

    然后整体:

    class TimerBloc extends Bloc<TimerEvent, TimerState> {
      TimerBloc() : super(TimerState()) {
    
    on<TimerStart>((event, emit) => emit(state.copyWith(isTicking: true)));
    on<TimerStop>((event, emit) => emit(state.copyWith(isTicking: false)));
    ...
    }
    

    至于您的期望,因此它们是不正确的,因为:

    每次状态更改只调用一次监听器(不包括 初始状态)不同于BlocBuilder中的生成器,并且是一个void函数。

    所以您仍然可以使用您的状态,但无法在侦听器中捕获初始状态。