gpt4 book ai didi

flutter - BLoC产生新状态后未更新BlocBuilder()

转载 作者:行者123 更新时间:2023-12-03 03:56:16 30 4
gpt4 key购买 nike

我是 flutter 朔迷离的BLoC模式的新手,我正尝试使用它重建一个凌乱的 flutter 应用程序。目前,我打算获取用户应用程序的列表,并使用ListView.builder()进行显示。问题是,每当我的AppsBloc的状态更改时,我的StatelessWidget都不会更新以显示新状态。我努力了:

  • 使用main.dart中的MultiBlocProvider()而不是将此appsBloc嵌套在包含整个应用程序
  • 的themeBloc中
  • 返回列表而不是Map,即使我的aux方法返回了正确的 map
  • 使用StatefulWidget,仅在ListView上使用BlocProvider()...

  • 我在类似的项目上一直在阅读有关此问题的信息,而问题可能出在Equatable。但是,由于我还是Equatable的新用户,因此我无法确定任何错误。我一直在VScode上调试项目,并在yield *行上设置了断点,这似乎还可以。尽管该窗口小部件未重建,但仍不断显示与InitialState相对应的文本。

    而且,即使所有状态都覆盖了toString(),BLoC也不会在控制台上打印任何内容

    这些是我的3个BLoC文件:

    apps_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();
    }
    }
    }

    apps_event.dart
    part of 'apps_bloc.dart';

    abstract class AppsEvent extends Equatable {
    const AppsEvent();

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

    class AppsLoadRequest extends AppsEvent {}


    apps_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";
    }


    main_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(),
    )
    ,
    ],
    );
    }
    }

    apps_screen.dart
    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");
    },
    ),
    ),
    ])
    ])),
    );
    }
    }

    最佳答案

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

    apps_screen.dart:

      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")
    );
    //...
    }


    或者即使没有 _appsBloc字段也可以执行以下操作:
    BlocProvider.of<AppsBloc>(context).add(AppsLoadRequest())

    关于flutter - BLoC产生新状态后未更新BlocBuilder(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61087287/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com