Flutter BLoC生成新状态后未更新BlocBuilder()

Flutter BLoC生成新状态后未更新BlocBuilder(),flutter,dart,bloc,Flutter,Dart,Bloc,我对flutter上的BLoC模式还不熟悉,我正试图用它重建一个混乱的flutter应用程序。目前,我打算获取用户应用程序的列表,并使用ListView.builder()显示它们。问题是,每当AppsBloc的状态发生变化时,我的无状态小部件都不会更新以显示新状态。我试过: 使用main.dart中的MultiBlocProvider(),而不是将此appsBloc嵌套在包含整个应用程序的themeBloc中 返回列表而不是映射,即使我的aux方法返回正确的映射 使用StatefulWidg

我对flutter上的BLoC模式还不熟悉,我正试图用它重建一个混乱的flutter应用程序。目前,我打算获取用户应用程序的列表,并使用ListView.builder()显示它们。问题是,每当AppsBloc的状态发生变化时,我的无状态小部件都不会更新以显示新状态。我试过:

  • 使用main.dart中的MultiBlocProvider(),而不是将此appsBloc嵌套在包含整个应用程序的themeBloc中
  • 返回列表而不是映射,即使我的aux方法返回正确的映射
  • 使用StatefulWidget,仅在ListView上使用BlocProvider()
我在类似的项目中读到过关于这个问题的文章,这个问题可能与Equatable有关。然而,由于我也是新使用Equatable的人,所以我一直无法识别这方面的任何错误。我一直在VScode上调试这个项目,在yield*行上有一个断点,看起来还可以。尽管如此,小部件并没有得到重建:它一直显示与InitialState对应的文本

此外,即使所有的州都有一个覆盖的toString()文件,该集团也不会在控制台上打印任何内容

以下是我的3个BLoC文件:

应用程序\u bloc.dart

import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:device_apps/device_apps.dart';
import 'package:equatable/equatable.dart';

part 'apps_event.dart';
part 'apps_state.dart';

class AppsBloc extends Bloc<AppsEvent, AppsState> {
  @override
  AppsState get initialState => AppsInitial();

  @override
  Stream<AppsState> mapEventToState(AppsEvent event) async* {
    yield AppsLoadInProgress();
    if (event is AppsLoadRequest) {
      yield* _mapAppsLoadSuccessToState();
      }
  }

  Stream<AppsState> _mapAppsLoadSuccessToState() async* {
    try {
      final allApps = await DeviceApps.getInstalledApplications(
          onlyAppsWithLaunchIntent: true, includeSystemApps: true);

      final listaApps = allApps
        ..sort((a, b) =>
            a.appName.toLowerCase().compareTo(b.appName.toLowerCase()));

      final Map<Application, bool> res =
          Map.fromIterable(listaApps, value: (e) => false);

      yield AppsLoadSuccess(res);
    } catch (_) {
      yield AppsLoadFailure();
    }
  }
}
导入'dart:async';
导入“包:bloc/bloc.dart”;
导入“包:设备应用程序/设备应用程序.dart”;
导入“包:equalable/equalable.dart”;
“应用程序和事件.dart”部分;
“应用程序州.省道”部分;
类AppsBloc扩展了Bloc{
@凌驾
AppsState get initialState=>AppsInitial();
@凌驾
流mapEventToState(AppsEvent事件)异步*{
收益率AppsLoadInProgress();
if(事件为AppsLocadRequest){
yield*_mappsLoadSuccessToState();
}
}
流\u mapAppsLoadSuccessToState()异步*{
试一试{
最终allApps=等待设备Apps.GetInstalledApplication(
仅适用于具有启动意图的应用程序:true,包括系统应用程序:true);
最终列表aapps=allApps
…排序((a,b)=>
a、 appName.toLowerCase().compareTo(b.appName.toLowerCase());
最终地图资源=
Map.fromIterable(listaApps,值:(e)=>false);
收益率AppsLoadSuccess(res);
}接住{
屈服于AppsLoadFailure();
}
}
}
apps\u event.dart

part of 'apps_bloc.dart';

abstract class AppsEvent extends Equatable {
  const AppsEvent();

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

class AppsLoadRequest extends AppsEvent {}

apps_bloc.dart'的一部分;
抽象类AppsEvent扩展了equalable{
常数AppsEvent();
@凌驾
列表获取道具=>[];
}
类AppsLocadRequest扩展AppsEvent{}
应用程序_state.dart

part of 'apps_bloc.dart';

abstract class AppsState extends Equatable {
  const AppsState();

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

class AppsInitial extends AppsState {
  @override
  String toString() => "State: AppInitial";
}

class AppsLoadInProgress extends AppsState {
  @override
  String toString() => "State: AppLoadInProgress";
}

class AppsLoadSuccess extends AppsState {
  final Map<Application, bool> allApps;
  const AppsLoadSuccess(this.allApps);

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

  @override
  String toString() => "State: AppLoadSuccess, ${allApps.length} entries";
}

class AppsLoadFailure extends AppsState {
  @override
  String toString() => "State: AppLoadFailure";
}

apps_bloc.dart'的一部分;
抽象类AppsState扩展了Equalable{
常量AppsState();
@凌驾
列表获取道具=>[];
}
类appsintial扩展了AppsState{
@凌驾
字符串toString()=>“状态:AppInitial”;
}
类AppsLoadInProgress扩展了AppsState{
@凌驾
字符串toString()=>“状态:AppLoadInProgress”;
}
类AppsLocadSuccess扩展了AppsState{
阿拉普斯最终地图;
const appsloadsucces(this.allApps);
@凌驾
列表获取道具=>[allApps];
@凌驾
String toString()=>“状态:AppLoadSuccess,${allApps.length}个条目”;
}
类AppsLoadFailure扩展了AppsState{
@凌驾
字符串toString()=>“状态:AppLoadFailure”;
}
主屏幕省道

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

  @override
  Widget build(BuildContext context) {
    return TabBarView(
        children: <Widget>[
          HomeScreen(),
          BlocProvider(
            create: (BuildContext context) => AppsBloc(),
            child: AppsScreen(),
          )
          ,
        ],
      );
  }
}
class AppsScreen extends StatelessWidget {
  const AppsScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
          body: Container(
          margin: EdgeInsets.fromLTRB(30, 5, 10, 0),
          child: Column(children: <Widget>[
            Row(
              children: <Widget>[
                Text("Apps"),
              ],
            ),
            Row(children: <Widget>[
              Container(
                width: MediaQuery.of(context).size.width - 50,
                height: MediaQuery.of(context).size.height - 150,
                child: BlocBuilder<AppsBloc, AppsState>(
                  builder: (BuildContext context, AppsState state) {
                    if (state is AppsLoadSuccess)
                      return Text("LOADED");
                    else if (state is AppsInitial)
                      return GestureDetector(
                          onTap: () => AppsBloc().add(AppsLoadRequest()),
                          child: Text("INITIAL"));
                    else if (state is AppsLoadInProgress)
                      return Text("LOADING...");
                    else if (state is AppsLoadFailure)
                      return Text("LOADING FAILED");
                  },
                ),
              ),
            ])
          ])),
    );
  }
}
class主屏幕扩展了无状态小部件{
常量主屏幕({Key}):超级(Key:Key);
@凌驾
小部件构建(构建上下文){
返回选项卡视图(
儿童:[
主屏幕(),
BlocProvider(
create:(BuildContext context)=>AppsBloc(),
子项:AppsScreen(),
)
,
],
);
}
}
apps\u screen.dart

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

  @override
  Widget build(BuildContext context) {
    return TabBarView(
        children: <Widget>[
          HomeScreen(),
          BlocProvider(
            create: (BuildContext context) => AppsBloc(),
            child: AppsScreen(),
          )
          ,
        ],
      );
  }
}
class AppsScreen extends StatelessWidget {
  const AppsScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
          body: Container(
          margin: EdgeInsets.fromLTRB(30, 5, 10, 0),
          child: Column(children: <Widget>[
            Row(
              children: <Widget>[
                Text("Apps"),
              ],
            ),
            Row(children: <Widget>[
              Container(
                width: MediaQuery.of(context).size.width - 50,
                height: MediaQuery.of(context).size.height - 150,
                child: BlocBuilder<AppsBloc, AppsState>(
                  builder: (BuildContext context, AppsState state) {
                    if (state is AppsLoadSuccess)
                      return Text("LOADED");
                    else if (state is AppsInitial)
                      return GestureDetector(
                          onTap: () => AppsBloc().add(AppsLoadRequest()),
                          child: Text("INITIAL"));
                    else if (state is AppsLoadInProgress)
                      return Text("LOADING...");
                    else if (state is AppsLoadFailure)
                      return Text("LOADING FAILED");
                  },
                ),
              ),
            ])
          ])),
    );
  }
}
class AppsScreen扩展了无状态小部件{
const-AppsScreen({Key}):super(Key:Key);
@凌驾
小部件构建(构建上下文){
返回脚手架(
主体:容器(
边距:LTRB(30,5,10,0)的边距,
子项:列(子项:[
划船(
儿童:[
文本(“应用程序”),
],
),
世界其他地区(儿童:[
容器(
宽度:MediaQuery.of(context).size.width-50,
高度:MediaQuery.of(context).size.height-150,
孩子:BlocBuilder(
生成器:(BuildContext上下文,AppsState状态){
if(状态为AppsLodSuccess)
返回文本(“已加载”);
else if(状态为应用)
返回手势检测器(
onTap:()=>AppsBloc().add(AppsLoadRequest()),
子项:文本(“首字母”);
else if(状态为AppsLoadInProgress)
返回文本(“加载…”);
else if(状态为AppsLoadFailure)
返回文本(“加载失败”);
},
),
),
])
])),
);
}
}

GestureDetector.onTap()中创建一个新的
AppsBloc()
,这是错误的。因此,您需要:

应用程序\u屏幕。省道:

  AppsBloc _appsBloc;

  @override
  void initState() {
    super.initState();

    _appsBloc = BlocProvider.of<AppsBloc>(context);
  }

//...

  @override
  Widget build(BuildContext context) {
    //...
    return GestureDetector(
      onTap: () => _appsBloc.add(AppsLoadRequest()),
      child: Text("INITIAL")
    );
    //...
  }


GestureDetector.onTap()
中创建一个新的
AppsBloc()
,这是错误的。因此,您需要:

应用程序\u屏幕。省道:

  AppsBloc _appsBloc;

  @override
  void initState() {
    super.initState();

    _appsBloc = BlocProvider.of<AppsBloc>(context);
  }

//...

  @override
  Widget build(BuildContext context) {
    //...
    return GestureDetector(
      onTap: () => _appsBloc.add(AppsLoadRequest()),
      child: Text("INITIAL")
    );
    //...
  }


这解决了我的问题,非常感谢!我以前也试过,但看起来我错过了一些重要的东西,现在它起作用了。干杯。这解决了我的问题,非常感谢!我以前也试过,但看起来我错过了一些重要的东西,现在它起作用了。干杯