Flutter - InheritedWidget - dispose

后端 未结 2 1678
被撕碎了的回忆
被撕碎了的回忆 2020-12-11 03:34

I was wondering if anybody knew a way to know when an InheritedWidget was disposed?

The reason of this question is that I am doing some experiments and I am using an

相关标签:
2条回答
  • 2020-12-11 03:57

    InheritedWidget behaves the same way as other Widget do. Their lifetime is really short: Usually not longer than one build call.

    If you want to store data for longer, InheritedWidget is not what you want. You'll need a State for that.

    Which also means that ultimately, you can use State's dispose for your bloc dispose.

    class BlocHolder extends StatefulWidget {
      final Widget child;
    
      BlocHolder({this.child});
    
      @override
      _BlocHolderState createState() => _BlocHolderState();
    }
    
    class _BlocHolderState extends State<BlocHolder> {
      final _bloc = new MyBloc();
    
      @override
      Widget build(BuildContext context) {
        return MyInherited(bloc: _bloc, child: widget.child,);
      }
    
    
      @override
      void dispose() {
        _bloc.dispose();
        super.dispose();
      }
    }
    
    class MyInherited extends InheritedWidget {
      final MyBloc bloc;
    
      MyInherited({this.bloc, Widget child}): super(child: child);
    
      @override
      bool updateShouldNotify(InheritedWidget oldWidget) {
        return oldWidget != this;
      }
    }
    
    
    class MyBloc {
      void dispose() {
    
      }
    }
    
    0 讨论(0)
  • 2020-12-11 04:03

    Inherited widgets behave very much like stateless widgets, which also do not have a dispose method. Inherited widgets are getting rebuilt frequently, and all the values stored inside of it would be lost (and without a proper updateShouldNotify implementation, the dependent widget trees will also be rebuilt frequently!).

    To solve this problem, you can utilize a StatefulWidget:

    import 'dart:async';
    
    import 'package:flutter/widgets.dart';
    
    class ApplicationProvider extends StatefulWidget {
      const ApplicationProvider({Key key, this.child}) : super(key: key);
    
      final Widget child;
    
      @override
      State<StatefulWidget> createState() => _ApplicationProviderState();
    }
    
    class _ApplicationProviderState extends State<ApplicationProvider> {
      final ApplicationBloc bloc = new ApplicationBloc();
    
      @override
      void dispose() {
        bloc.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return _ApplicationProvider(
          bloc: bloc,
          child: widget.child,
        );
      }
    }
    
    class _ApplicationProvider extends InheritedWidget {
      _ApplicationProvider({
        Key key,
        this.bloc,
        Widget child,
      }) : super(key: key, child: child);
    
      final ApplicationBloc bloc;
    
      @override
      bool updateShouldNotify(_ApplicationProvider oldWidget) {
        return bloc != oldWidget.bloc;
      }
    }
    
    class ApplicationBloc {
      ApplicationBloc of(BuildContext context) {
        final _ApplicationProvider provider = context.inheritFromWidgetOfExactType(_ApplicationProvider);
        return provider.bloc;
      }
    
      int _counter;
      StreamController<int> _counterController = new StreamController<int>.broadcast();
      Sink get inCounter => _counterController;
    
      Stream<int> get outCounter => _counterController.stream;
    
      ApplicationBloc() {
        _counter = 0;
      }
    
      void increment() {
        _counter++;
        inCounter.add(_counter);
      }
    
      int get counter => _counter;
    
      void dispose() {
        _counterController.close();
      }
    }
    
    0 讨论(0)
提交回复
热议问题