【问题标题】:the current state in mapEventToState in Flutter Bloc is not yieldFlutter Bloc 中 mapEventToState 中的当前状态不是 yield
【发布时间】:2020-07-21 10:44:49
【问题描述】:

我正在尝试制作一个简单的应用程序来测试 BloC 模式,但是,BloC 模式的当前版本发生了变化,“当前状态”现在不使用 mapEventToState 方法作为参数发送,而是根据在线文档,您只能用“状态”替换它,但它不适用于我,

这是我的代码:

class CounterBloc extends Bloc<CounterEvent, CounterState> {

  void onIncrement(){
     add(IncrementEvent());
  }

  void onDecrement() {
     add(DecrementEvent());
  }

  @override
  // TODO: implement initialState
  CounterState get initialState => CounterState.initial();

  @override
  Stream<CounterState> mapEventToState(CounterEvent event) async* {
    if (event is IncrementEvent) {
      yield state..counter += 1;
    } else if (event is DecrementEvent) {
      yield state..counter -= 1;
    }
  }
}

这是 Counter 状态类

class CounterState {
  int counter;

  CounterState._();

  factory CounterState.initial() {
    return CounterState._()..counter = 0;
  }
}

这是我的主要应用程序 dart 文件

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);


  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => CounterBloc(),
      child: CounterWidget(widget: widget),
    );
  }
}

class CounterWidget extends StatelessWidget {

  final MyHomePage widget;

  const CounterWidget({Key key, @required this.widget}) :super (key: key);

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: BlocBuilder(
          bloc: BlocProvider.of<CounterBloc>(context),
          builder: (context, CounterState state) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    'You have pushed the button this many times:',
                  ),
                  Text(
                    '${state.counter}',
                    style: Theme.of(context).textTheme.display1,
                  ),
                ],
              ),
            );
          },
        ),
        floatingActionButton: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            FloatingActionButton(
              onPressed: () => BlocProvider.of<CounterBloc>(context).onIncrement(),
              tooltip: 'Increment',
              child: Icon(Icons.add),
            ),
            SizedBox(width: 10,),
            FloatingActionButton(
              onPressed: () => BlocProvider.of<CounterBloc>(context).onDecrement(),
              tooltip: 'Decrement',
              child: Icon(Icons.remove),
            ),
          ],
        )
    );
  }
} 

请问谁能帮我解决这个问题?

【问题讨论】:

    标签: android-studio flutter dart


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    第 1 步:在CounterState 中添加CounterState({this.counter});
    Step 2 : yield state..counter += 1; 不会引起Widget build ,请改成yield CounterState(counter: state.counter + 1);

    工作演示

    完整代码

    import 'package:flutter/material.dart';
    import 'package:bloc/bloc.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    
    abstract class CounterEvent {}
    
    class IncrementEvent extends CounterEvent {}
    
    class DecrementEvent extends CounterEvent {}
    
    void main() => runApp(MyApp());
    
    class CounterState {
      int counter;
    
      CounterState._();
    
      CounterState({this.counter}); //add this line
    
      factory CounterState.initial() {
        return CounterState._()..counter = 0;
      }
    }
    
    class CounterBloc extends Bloc<CounterEvent, CounterState> {
      void onIncrement() {
        add(IncrementEvent());
      }
    
      void onDecrement() {
        add(DecrementEvent());
      }
    
      @override
      // TODO: implement initialState
      CounterState get initialState => CounterState.initial();
    
      @override
      Stream<CounterState> mapEventToState(CounterEvent event) async* {
        if (event is IncrementEvent) {
          //yield state..counter += 1;
          yield CounterState(counter: state.counter + 1);
        } else if (event is DecrementEvent) {
          //yield state..counter -= 1;
          yield CounterState(counter: state.counter - 1);
        }
      }
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return BlocProvider(
          create: (context) => CounterBloc(),
          child: CounterWidget(widget: widget),
        );
      }
    }
    
    class CounterWidget extends StatelessWidget {
      final MyHomePage widget;
    
      const CounterWidget({Key key, @required this.widget}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: BlocBuilder(
              bloc: BlocProvider.of<CounterBloc>(context),
              builder: (context, CounterState state) {
                return Center(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text(
                        'You have pushed the button this many times:',
                      ),
                      Text(
                        '${state.counter}',
                        style: Theme.of(context).textTheme.display1,
                      ),
                    ],
                  ),
                );
              },
            ),
            floatingActionButton: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                FloatingActionButton(
                  onPressed: () =>
                      BlocProvider.of<CounterBloc>(context).onIncrement(),
                  tooltip: 'Increment',
                  child: Icon(Icons.add),
                ),
                SizedBox(
                  width: 10,
                ),
                FloatingActionButton(
                  onPressed: () =>
                      BlocProvider.of<CounterBloc>(context).onDecrement(),
                  tooltip: 'Decrement',
                  child: Icon(Icons.remove),
                ),
              ],
            ));
      }
    }
    

    【讨论】:

    • 好的,这很好,但我有一个问题。触发 onPressed 时,这个解决方案是否比在 main.dart 文件中使用 setState 更好?
    猜你喜欢
    • 2021-12-05
    • 2022-07-10
    • 1970-01-01
    • 2021-04-21
    • 2021-03-19
    • 2020-05-06
    • 2020-07-05
    • 2020-01-14
    • 1970-01-01
    相关资源
    最近更新 更多