Flutter BLoC 无法更新我的 bool 值列表

标签 flutter dart bloc

所以,我尝试学习 flutter,尤其是 BLoC 方法,并用 BLoC 制作了一个简单的 ToggleButtons。看起来像这样

切换UI.dart

class Flutter501 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 50 With Bloc Package',
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              BlocProvider<ToggleBloc>(
                builder: (context) => ToggleBloc(maxToggles: 4),
                child: MyToggle(),
              )
            ],
          ),
        ),
      ),
    );
  }
}

class MyToggle extends StatelessWidget {
  const MyToggle({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    ToggleBloc bloc = BlocProvider.of<ToggleBloc>(context);
    return BlocBuilder<ToggleBloc, List<bool>>(
      bloc: bloc,
      builder: (context, state) {
        return ToggleButtons(
          children: [
            Icon(Icons.arrow_back),
            Icon(Icons.arrow_upward),
            Icon(Icons.arrow_forward),
            Icon(Icons.arrow_downward),
          ],
          onPressed: (idx) {
            bloc.dispatch(ToggleTap(index: idx));
          },
          isSelected: state,
        );
      },
    );
  }
}

ToogleBloc.dart

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';

abstract class ToggleEvent extends Equatable {
  const ToggleEvent();
}

class ToggleTap extends ToggleEvent {
  final int index;

  ToggleTap({this.index});

  @override
  // TODO: implement props
  List<Object> get props => [];
}

class ToggleBloc extends Bloc<ToggleEvent, List<bool>> {
  final List<bool> toggles = [];

  ToggleBloc({
    @required int maxToggles,
  }) {
    for (int i = 0; i < maxToggles; i++) {
      this.toggles.add(false);
    }
  }

  @override
  // TODO: implement initialState
  List<bool> get initialState => this.toggles;

  @override
  Stream<List<bool>> mapEventToState(ToggleEvent event) async* {
    // TODO: implement mapEventToState
    if (event is ToggleTap) {
      this.toggles[event.index] = !this.toggles[event.index];
    }

    yield this.toggles;
  }
}

当我尝试点击/按下其中一个按钮时出现问题,但它不想更改为事件按钮。但每当我尝试按“热重载”时它就会起作用。就像每当按下按钮时我都必须进行 setState。

最佳答案

BlocBuilder.builder仅当 State 时才执行方法变化。所以在你的情况下 StateList<bool>您只需更改其中的特定索引并生成相同的对象。因此,BlocBuilder 无法确定列表是否发生更改,因此不会触发 UI 的重建。

参见https://github.com/felangel/bloc/blob/master/docs/faqs.md有关 flutter_bloc 中的解释文档:

Equatable properties should always be copied rather than modified. If an Equatable class contains a List or Map as properties, be sure to use List.from or Map.from respectively to ensure that equality is evaluated based on the values of the properties rather than the reference.

解决方案

在您的 ToggleBloc 中,像这样更改 List,因此它创建了一个全新的 List 对象:

  @override
  Stream<List<bool>> mapEventToState(ToggleEvent event) async* {
    // TODO: implement mapEventToState
    if (event is ToggleTap) {
      this.toggles[event.index] = !this.toggles[event.index];
      this.toggles = List.from(this.toggles);
    }

    yield this.toggles;
  }

此外,请确保设置 props对于您的事件,尽管对于这个具体问题来说并不重要。

关于Flutter BLoC 无法更新我的 bool 值列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65379743/

相关文章:

flutter - 当我的小部件使用字符串ID进行引用时,如何将参数传递给有状态的小部件?

dart - Dart导入本地包不带类

android - Flutter 谷歌地图和 firebase 不能一起工作

flutter - 一个 VideoPlayerController 销毁后使用。一旦在 VideoPlayerController 上调用了 dispose(),就不能再使用它

flutter - ConnectionState在主类中更改两次

flutter - 为什么建议在大型项目中使用 Bloc 模式?

image - 在 Flutter 应用程序中添加 360 VR 照片查看器

gradle - 如何解决:Android Gradle插件仅支持Kotlin Gradle插件1.3.10及更高版本。

dart - Flutter - 如何在 AppBar 不存在时设置状态栏颜色

Flutter BLoC 事件竞争条件