Flutter-InheritedWidget-处理

时间:2018-08-04 23:14:22

标签: flutter

我想知道是否有人知道何时处理InheritedWidget?

这个问题的原因是我正在做一些实验,并且正在使用InheritedWidget作为BLoC的提供者。 此BLoC在InheritedWidget级别初始化,并使用StreamController。

由于不建议关闭StreamController,因此我正在寻找解决方案。

下面是一段代码(用于实验的傻瓜代码)来说明问题:

///
/// ApplicationProvider
/// 
/// A provider of ApplicationBloc
/// 
class ApplicationProvider extends InheritedWidget {
  //
  // Initialization of the BLoC
  //
  final ApplicationBloc bloc = new ApplicationBloc();

  ApplicationProvider({Key key, Widget child}) : super(key: key, child: child);

  @override
  bool updateShouldNotify(_) => true;

  static ApplicationBloc of(BuildContext context, [bool redraw = true]) {
    return redraw ? (context.inheritFromWidgetOfExactType(ApplicationProvider) as ApplicationProvider).bloc
                  : (context.ancestorWidgetOfExactType(ApplicationProvider) as ApplicationProvider).bloc;
  }
}

//
// The BLoC
//   
class ApplicationBloc {

  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;

  //
  // How could I call this method ???
  //
  void dispose(){
    _counterController.close();
  }
}

所以主要问题是“ 如何调用BLoC的dispose()方法”?

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:10)

InheritedWidget的行为与其他Widget相同。 它们的寿命很短:通常不超过一个build通话。

如果您想存储更长的数据,InheritedWidget不是您想要的。为此,您需要一个State

这也意味着最终,您可以将State的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() {

  }
}

答案 1 :(得分:0)

继承的窗口小部件的行为非常类似于无状态窗口小部件,后者也没有dispose方法。继承的窗口小部件会经常重建,并且存储在其中的所有值都会丢失(并且如果没有适当的updateShouldNotify实现,依赖的窗口小部件树也将被频繁重建!)。

要解决此问题,您可以使用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();
  }
}