我正在使用 BLOC 制作一个简单的计数器应用程序,但是当我递增/递减时我的计数器没有更新?我使用 BlocBuilder 构建 UI

I am using BLOC to make a simple counter app , but my counter is not updating when I am incrementing / decrementing it? I used BlocBuilder to build UI

我已将 MaterialApp 包装在 BlocProvider 下,并且我还使用 BlocBuilder 构建 UI(反文字) 我有两个浮动操作按钮,每个按钮分别调用 Incrementevent() 和 Decrementevent(),但 UI 仍然没有改变。 请提出解决方案。

我的 main.dart 文件

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => CounterBloc(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final _counterBloc = CounterBloc();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: BlocBuilder<CounterBloc, CounterState>(
        builder: (context, 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.headline4,
                ),
              ],
            ),
          );
        },
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            onPressed: () => _counterBloc.add(Incrementevent()),
            tooltip: 'Decrement',
            child: Icon(Icons.remove),
          ),
          SizedBox(width: 10),
          FloatingActionButton(
            onPressed: () => _counterBloc.add(Decrementevent()),
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _counterBloc.close();
    super.dispose();
  }
}

我的 counter_event 文件

part of 'counter_bloc.dart';

@immutable
abstract class CounterEvent {}

class Incrementevent extends CounterEvent {}

class Decrementevent extends CounterEvent {}

我的 counter_state 文件

part of 'counter_bloc.dart';

@immutable
abstract class CounterState {
  final int counter;
  const CounterState(this.counter);
}

class CounterInitial extends CounterState {
  CounterInitial(int counter) : super(counter);
}

我的 counter_bloc 文件

import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';

part 'counter_event.dart';
part 'counter_state.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial(0));

  @override
  Stream<CounterState> mapEventToState(
    CounterEvent event,
  ) async* {
    if (event is Incrementevent) {
      yield CounterInitial(state.counter + 1);
    } else if (event is Decrementevent) {
      yield CounterInitial(state.counter - 1);
    }
  }
}

TL;DR 您正在创建同一个 BLoC 的两个实例,因此通过在一个 BLoC 上触发事件,另一个不会得到更新。

MyApp 小部件中,您创建一个 BLoC 实例并使用 BlocProvider 将其提供给小部件树 - 这里的一切都很完美。

但是,在 _MyHomePageState 中,您正在创建同一 CounterBloc 的另一个实例并使用它来添加事件。这意味着,您在与之前提供的不同的 BLoC 上运行。

要解决此问题,您应该获取注入的 BLoC 实例并对其进行操作。由于 BLoC 库依赖于 provider,您可以像这样解析注入的 BLoC:

@override
Widget build(BuildContext context) {
  final counterBloc = context.watch<CounterBloc>();
  ...
  floatingActionButton: Row(
    mainAxisAlignment: MainAxisAlignment.end,
    children: [
      FloatingActionButton(
        onPressed: () => counterBloc.add(Incrementevent()),
        tooltip: 'Decrement',
        child: Icon(Icons.remove),
      ),
      SizedBox(width: 10),
      FloatingActionButton(
        onPressed: () => counterBloc.add(Decrementevent()),
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    ],
  ),
  ...
}

或者这样:

@override
Widget build(BuildContext context) {
  ...
  floatingActionButton: Row(
    mainAxisAlignment: MainAxisAlignment.end,
    children: [
      FloatingActionButton(
        onPressed: () => context.read<CounterBloc>().add(Incrementevent()),
        tooltip: 'Decrement',
        child: Icon(Icons.remove),
      ),
      SizedBox(width: 10),
      FloatingActionButton(
        onPressed: () => context.read<CounterBloc>().add(Decrementevent()),
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    ],
  ),
  ...
}