如何使用Provider在Hot Reload上保持Flutter Global BloC状态?

肯尼

每当执行热重装时,我似乎都会丢失应用程序状态。

我正在使用BloC提供程序来存储应用程序状态。这在main.dart中的应用程序级别传递,并在子页面上使用。在视图的初始加载时,将显示该值。我可以浏览该应用程序,并且状态仍然存在。但是,当我执行热重装时,我会丢失值和看似状态。

如何解决此问题,以便在热重装时保留状态?

团体提供商

abstract class BlocBase {
  void dispose();
}

class BlocProvider<T extends BlocBase> extends StatefulWidget {
  BlocProvider({
    Key key,
    @required this.child,
    @required this.bloc,
  }): super(key: key);

  final T bloc;
  final Widget child;

  @override
  _BlocProviderState<T> createState() => _BlocProviderState<T>();

  static T of<T extends BlocBase>(BuildContext context){
    final type = _typeOf<BlocProvider<T>>();
    BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
    return provider.bloc;
  }

  static Type _typeOf<T>() => T;
}

class _BlocProviderState<T> extends State<BlocProvider<BlocBase>>{
  @override
  void dispose(){
    widget.bloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context){
    return widget.child;
  }
}
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return BlocProvider<ApplicationStateBloc>(
      bloc: ApplicationStateBloc(),
      child: MaterialApp(
        title: 'Handshake',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: LoadingPage(),
      )
    );
  }
}
class ProfileSettings extends StatefulWidget {
  @override
  _ProfileSettingsState createState() => _ProfileSettingsState();
}

class _ProfileSettingsState extends State<ProfileSettings>{
  ApplicationStateBloc _applicationStateBloc;

  @override
  void initState() {
    super.initState();
    _applicationStateBloc = BlocProvider.of<ApplicationStateBloc>(context);
  }

  @override
  void dispose() {
    _applicationStateBloc?.dispose();
    super.dispose();
  }

  Widget emailField() {
    return StreamBuilder<UserAccount>(
      stream: _applicationStateBloc.getUserAccount,
      builder: (context, snapshot){
        if (snapshot.hasData) {
          return Text(snapshot.data.displayName, style: TextStyle(color: Color(0xFF151515), fontSize: 16.0),);
        }
        return Text('');
      },
    );
  }

  @override
  Widget build(BuildContext context) {

    return BlocProvider<ApplicationStateBloc>(
      bloc: _applicationStateBloc,
      child: Scaffold(
        backgroundColor: Colors.white,
        body: SafeArea(
          child: Column(
            children: <Widget>[
              emailField(),
              .... // rest of code
class ApplicationStateBloc extends BlocBase {

  var userAccountController = BehaviorSubject<UserAccount>();
  Function(UserAccount) get updateUserAccount => userAccountController.sink.add;
  Stream<UserAccount> get getUserAccount => userAccountController.stream;

  @override
  dispose() {
    userAccountController.close();
  }

}
亚历克斯·科斯特

我面临着同样的问题。继承的窗口小部件很难处理bloc的资源。另一方面,有状态的小部件允许进行处理,但是在您使用的实现中,它不会将集团保持在该状态,从而导致小部件重建时状态丢失。

经过一些试验,我想出了一种将两者结合的方法:

class BlocHolder<T extends BlocBase> extends StatefulWidget {
  final Widget child;
  final T Function() createBloc;

  BlocHolder({
    @required this.child,
    @required this.createBloc
  });

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

class _BlocHolderState<T extends BlocBase> extends State<BlocHolder> {
  T _bloc;

  Function hello;

  @override
  void initState() {
    super.initState();
    _bloc = widget.createBloc();
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      child: widget.child,
      bloc: _bloc,
    );
  }

  @override
  void dispose() {
    _bloc.dispose();
    super.dispose();
  }
}

Bloc持有人在createState()中创建bloc并将其持久化。它还在dispose()中处理了bloc的资源。

class BlocProvider<T extends BlocBase> extends InheritedWidget {
  final T bloc;

  const BlocProvider({
    Key key,
    @required Widget child,
    @required T bloc,
  })
      : assert(child != null),
        bloc = bloc,
        super(key: key, child: child);

  static T of<T extends BlocBase>(BuildContext context) {
    final provider = context.inheritFromWidgetOfExactType(BlocProvider) as BlocProvider;
    return provider.bloc;
  }

  @override
  bool updateShouldNotify(BlocProvider old) => false;
}

顾名思义,BlocProvider仅负责将bloc提供给嵌套的小部件。

所有集团都扩展了BlocBase类

abstract class BlocBase {
  void dispose();
}

这是一个用法示例:

class RouteHome extends MaterialPageRoute<ScreenHome> {
 RouteHome({List<ModelCategory> categories, int position}): super(builder: 
    (BuildContext ctx) => BlocHolder(
        createBloc: () => BlocMain(ApiMain()),
        child: ScreenHome(),
      ));
    }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

禁用GLOBAL INTERRUPT时,中断是否保持其状态?

如何保持状态,在Flutter中滚动?

使用bloc保持存储库实例“处于活动状态”

如何在Flutter Hot Reload上保持BLoC状态?

如何使用BLoC模式管理表单状态?

在Flutter中请求位置时,BloC不会产生状态

Flutter BloC布尔值更新状态

Flutter状态管理(BloC):无状态与有状态小部件

Flutter从其他Bloc监听Bloc状态

Flutter Bloc侦听器内部的延迟状态检查

Flutter Bloc状态无法正确更新

使用Flutter BLOC收听事件而不是状态

Flutter Bloc状态无论如何都不会更新

有状态小部件外部的调用方法以使用Flutter Bloc更新UI

Flutter Bloc侦听器未侦听状态更改

Flutter Bloc:屈服状态不会触发小部件重建

Flutter无法使用PageTransitionSwitcher保持标签状态

flutter_bloc:^ 6.1.1不更改状态

Flutter bloc:更新状态不会重新调用 BlocBuilder

如何在 Flutter 中开发通用的 bloc 和 bloc provider?

Flutter Bloc 冲突状态

Flutter bloc 库 - 如何定义状态对象

无法使用 BlockBuilder() 和 TextField() 的 onChanged 属性更新状态。[Flutter_Bloc]

使用 flutter_form_bloc 卡在 FormBlocSuccess 中的 Flutter Form 状态

flutter bloc 以及 bloc 状态更改如何在同时更新 Widget/UI 之前触发第二次异步调用?(附代码)

使用 Flutter bloc_test 测试特定状态

Flutter BLOC 状态更新但始终为空值

Flutter Bloc:一个屏幕内的许多状态,如何处理?

Flutter Bloc 表单状态和 WillPopScope